python 查看對象屬性相關方法(__dict__, dir(), vars(), locals())


1. 對象 _dict_

object.__dict__一般是字典或其他映射對象,用來存儲一個對象(可寫的)的屬性。

    A dictionary or other mapping object used to store an object’s (writable) attributes.

內建類型對象中是不存在這個屬性的。內建對象訪問會出現AttributeError錯誤。

>>> lst = [1, 2]
>>> lst.__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute '__dict__'

類對象Class.__dict__只返回當前類的屬性字典,但不包含其基類的屬性。dir(Class)會返回當前類以及它的所有基類的類屬性名,即當前類及所有基類的__dict__鍵值。
實例對象obj.__dict__返回實例對象綁定的屬性字典。dir(obj)會返回實例屬性和構造類以及所有基類的屬性列表。

class ClassA:

    num_A = 1

    def foo_A(self):
        pass

    def __str__(self):
        return 'this is ClassA'


class ClassB(ClassA):

    num_B = 2

    def __init__(self, name='ClassB'):
        self.name = name

    def foo_B(self):
        pass

print(ClassB.__dict__)  # 類對象的__dict__不包含基類的屬性
# {'__module__': '__main__', 'num_B': 2, '__doc__': None, 'foo_B': 
# <function ClassB.foo_B at 0x7f1a78dadbf8>, '__init__': <function ClassB.__init__ at 0x7f1a78dadb70>}

print(dir(ClassB))  # 會返回當前類以及它的所有基類的`__dict__`鍵值列表
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
# '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
# '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', 
# '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 
# '__str__', '__subclasshook__', '__weakref__', 'foo_A', 'foo_B', 'num_A', 'num_B']

objB = ClassB()

print(objB.__dict__)
# {'name': 'ClassB'}

objB.grade = 123  # 運行時增加實例屬性

print(objB.__dict__)
# {'grade': 123, 'name': 'ClassB'}

print(dir(objB))
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
# '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__',
# '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
# '__subclasshook__', '__weakref__', 'foo_A', 'foo_B', 'name', 'num_A', 'num_B']

lst = dir(objB) 
lst.remove('name')
lst.remove('grade')
print(lst == dir(ClassB))   # dir(obj)除去obj綁定的屬性和dir(class)得到內容的一樣
# True

### 2. dir() 方法

dir([object])

Without arguments, return the list of names in the current local scope. With an argument, attempt to
return a list of valid attributes for that object.
不帶參數時,返回當前范圍內名稱列表;
帶參數時,返回對象有效屬性的列表。

If the object has a method named __dir__(), this method will be called and must return the list of
attributes. This allows objects that implement a custom __getattr__() or __getattribute__() function to
customize the way dir() reports their attributes.
如果參數對象有方法__dir__(),該方法將被調用。

If the object does not provide __dir__(), the function tries its best to gather information from the
object’s __dict__ attribute, if defined, and from its type object. The resulting list is not
necessarily complete, and may be inaccurate when the object has a custom __getattr__().
如果對象沒有__dir__()方法

The default dir() mechanism behaves differently with different types of objects, as it attempts to
produce the most relevant, rather than complete, information:

    If the object is a module object, the list contains the names of the module’s attributes.
    作用於模塊
    If the object is a type or class object, the list contains the names of its attributes, and
    recursively of the attributes of its bases.
    作用於類對象
    Otherwise, the list contains the object’s attributes’ names, the names of its class’s attributes,
    and recursively of the attributes of its class’s base classes.
    作用與實例對象
  1. dir()不帶參數時,返回當前范圍內名稱列表。和locals(),vars()不帶參數類似,后面返回的是 {名稱列表,值} 的字典。
  2. dir(module) 作用於模塊時,返回模塊的屬性列表。即模塊struct.__dict__的鍵值列表。
import struct

print(dir())   # show the names in the module namespace
# ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', 
# '__name__', '__package__', '__spec__', 'struct']

print(set(locals().keys()) == set(dir()))
# True

print(dir(struct))   # show the names in the struct module 
# ['Struct', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__',
# '__package__', '__spec__', '_clearcache', 'calcsize', 'error', 'iter_unpack', 'pack', 'pack_into',
# 'unpack', 'unpack_from']

print(set(dir(struct)) == set(struct.__dict__.keys()))
# True
  1. dir(obj)作用與實例對象,且它的構造類或基類有__dir__方法,dir(obj)返回自定義的列表內容。
class ClassA:

    num_A = 1

    def foo_A(self):
        pass

    def __str__(self):
        return 'this is ClassA'

    def __dir__(self):
        return ['height', 'color', '222']

class ClassB(ClassA):

    num_B = 2

    def __init__(self, name='ClassB'):
        self.name = name

    def foo_B(self):
        pass

objB = ClassB()
objB.grade = 123

print(dir(objB))
# ['222', 'color', 'height']

4)當dir(obj)作用於實例對象,且它的構造類或基類沒有__dir__方法,則dir(obj)返回obj的實例屬性,還有構造類及基類的類屬性。

5)當dir(class作用於類對象,返回當前類及所有基類的類屬性列表。

class ClassA:

    num_A = 1

    def foo_A(self):
        pass

    def __str__(self):
        return 'this is ClassA'

    # def __dir__(self):
    #     return ['height', 'color', '222']

class ClassB(ClassA):

    num_B = 2

    def __init__(self, name='ClassB'):
        self.name = name

    def foo_B(self):
        pass
        
print(dir(ClassB))
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', 
# '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
# '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', 
# '__reduce__', '__reduce_ex__', '__repr__','__setattr__', '__sizeof__', 
# '__str__', '__subclasshook__', '__weakref__', 'foo_A', 'foo_B', 'num_A', 'num_B']

objB = ClassB()
objB.grade = 123
print(dir(objB))
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', 
# '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', 
# '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', 
# '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
# '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'foo_A', 
# 'foo_B', 'grade', 'name', 'num_A', 'num_B']

### 3. [vars()](https://docs.python.org/3.5/library/functions.html?highlight=vars#vars) 和 [locals()](https://docs.python.org/3.5/library/functions.html?highlight=vars#locals) `vars([object])`:
Return the __dict__ attribute for a module, class, instance, or any other object with a __dict__
attribute.

Objects such as modules and instances have an updateable __dict__ attribute; however, other objects may
have write restrictions on their __dict__ attributes (for example, classes use a types.MappingProxyType
to prevent direct dictionary updates).

Without an argument, vars() acts like locals(). Note, the locals dictionary is only useful for reads
since updates to the locals dictionary are ignored.

vars([object])就是返回對象__dict__的內容,無論是類對象還是實例對象,vars([object]) == object.__dict__。當然,參數對象需要有一個__dict__屬性。同樣的,內建對象沒有__dict__屬性會報TypeError錯誤。

>>> lst = [1, 2]
>>> vars(lst)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: vars() argument must have __dict__ attribute
class ClassA:

    num_A = 1

    def foo_A(self):
        pass

    def __str__(self):
        return 'this is ClassA'

    # def __dir__(self):
    #     return ['height', 'color', '222']

class ClassB(ClassA):

    num_B = 2

    def __init__(self, name='ClassB'):
        self.name = name

    def foo_B(self):
        pass
        
objB = ClassB()
objB.grade = 123


print(vars(ClassB) == ClassB.__dict__)
# True
print(vars(objB) == objB.__dict__)
# True

locals()返回調用者當前局部名稱空間的字典。在一個函數內部,局部名稱空間代表在函數執行時候定義的所有名字,locals()函數返回的就是包含這些名字的字典。

Update and return a dictionary representing the current local symbol table. Free variables are returned by locals() when it is called in function blocks, but not in class blocks.

Note
The contents of this dictionary should not be modified; changes may not affect the 
values of local and free variables used by the interpreter.
print(locals())
# {'__name__': '__main__', '__file__': '/home/eliefly/PycharmProjects/test_folder/test.py', 
# '__spec__': None, '__cached__': None, '__doc__': None, 
# '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fadedf59518>, 
# '__builtins__': <module 'builtins' (built-in)>, '__package__': None}

print(vars() == locals())
# True


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM