什么';python中dir和dict最大的区别是什么

什么';python中dir和dict最大的区别是什么,python,introspection,Python,Introspection,输出: class C(object): def f(self): print self.__dict__ print dir(self) c = C() c.f() 为什么self中没有“f”.\uuuu dict\uuudir()所做的远不止是查找\uu dict\uu 首先,dir()是一种API方法,它知道如何使用诸如\uu dict\uuu之类的属性来查找对象的属性 但并非所有对象都具有\uuuu dict\uuu属性。例如,如果要将添加到自定

输出:

class C(object):
    def f(self):
        print self.__dict__
        print dir(self)
c = C()
c.f()
为什么self中没有“f”.\uuuu dict\uuu

dir()
所做的远不止是查找
\uu dict\uu
首先,
dir()
是一种API方法,它知道如何使用诸如
\uu dict\uuu
之类的属性来查找对象的属性

但并非所有对象都具有
\uuuu dict\uuu
属性。例如,如果要将添加到自定义类,则该类的实例将不具有
\uu dict\uu
属性,但
dir()
仍可以列出这些实例上的可用属性:

{}

['__class__', '__delattr__','f',....]
dir()
对实例做了什么 Python实例有自己的
\uuuu dict\uuu
,但它们的类也有:

>>> [].__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute '__dict__'
>>> dir([])
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
因为属性被添加到类
\uuuuu dict\uuuu

>>> f = Foo()
>>> f.ham
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'ham'
>>> Foo.ham = 'eggs'
>>> f.ham
'eggs'
请注意实例
\uuuu dict\uuuu
是如何保留为空的。Python对象的属性查找遵循从实例到类型再到父类的对象层次结构来搜索属性

仅当您直接在实例上设置属性时,才会看到该属性反映在实例的
\uuuu dict\uuu
中,而类
\uuuu dict\uu
保持不变:

>>> Foo.__dict__['ham']
'eggs'
>>> f.__dict__
{}
太长,读不下去了还是总结
dir()
不仅仅是查找对象的
\uuu dict\uuuu
(有时甚至不存在),它还将使用对象的遗产(其类或类型,以及该类或类型的任何超类或父类)为您提供所有可用属性的完整图片


实例
\uuuu dict\uuuu
只是该实例上的“本地”属性集,并不包含该实例上可用的所有属性。相反,您还需要查看类和类的继承树。

函数
f
属于类
C
的字典<代码>c.uu dict_uu生成特定于实例的属性
c

>>> f.stack = 'overflow'
>>> f.__dict__
{'stack': 'overflow'}
>>> 'stack' in Foo.__dict__
False
C.\uu dict\uuu
将产生类
C
的属性,包括函数
f

>>> class C(object):
    def f(self):
        print self.__dict__


>>> c = C()
>>> c.__dict__
{}
>>> c.a = 1
>>> c.__dict__
{'a': 1}

dir
如果实现,还将研究
\uuuu dir\uuuu
,它可以为那些甚至没有实现为形式属性或属性,但只是在
\uuu getattr\uuuuu
中缓慢实现的东西返回字符串。@PaulMcGuire:我不想详细说明
dir()
的功能;这是一个很长的答案,我不需要包含那个细节来让大家明白这一点。:-)请参阅以获得更简明的答案。@Davos:a
属性
对象是一个存在于类上而不是实例上的描述符对象。属性getter、setter或deleter的工作完全依赖于实现。属性可以随心所欲地执行任何操作,它根本不必对实例执行任何操作<实例上的code>dir()仍将列出类上的任何属性以及实例上的任何属性
\Uu dict\Uu
,因此
DatasourceItem
实例上的
dir()
将显示类上定义的
connections
属性和实例上的
\U connections
属性。@Davos:是的,这完全是意料之中的事。
DatasourceItem.id
属性
对象位于类上,而不是实例上
instance.id
将触发getter方法,然后返回
self.\u id
,其中
self.\u id
是实例上的一个属性。
>>> f.stack = 'overflow'
>>> f.__dict__
{'stack': 'overflow'}
>>> 'stack' in Foo.__dict__
False
>>> class C(object):
    def f(self):
        print self.__dict__


>>> c = C()
>>> c.__dict__
{}
>>> c.a = 1
>>> c.__dict__
{'a': 1}
>>> C.__dict__
dict_proxy({'__dict__': <attribute '__dict__' of 'C' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'C' objects>, '__doc__': None, 'f': <function f at 0x0313C1F0>})
>>> c.a = 1
>>> c.__dict__
{'a': 1}