这是不太一样的东西。 dir()
是省略属性,getattr()
和hasattr()
会找到的诊断工具。
从dir()
documentation:
默认dir()
机制不同类型的对象的不同表现,因为它试图产生最相关的,而不是完整的,信息:
- 如果该对象是一个模块对象,该列表包含模块属性的名称。
- 如果对象是一个类型或类对象,则该列表包含其属性的名称,并递归地显示其基础的属性。
- 否则,该列表包含对象的属性名称,其类属性的名称以及其类的基类的属性的递归。
和
注意:由于dir()
提供主要是使用的便利性,在一个交互式提示,它试图比它试图提供一个有趣的 集名称更多的提供严格或一致的定义的一组名称,其详细行为可能会在 版本中发生变化。例如,当参数是一个类时,metaclass
属性不在结果 列表中。
强调我的。
这意味着hasattr()
会发现元类提供属性,但dir()
不会,什么是发现可以不同翻过的Python版本作为函数的定义是提供调试方便,不完备性。
演示具体的元类场景,其中hasattr()
发现元类定义的属性:
>>> class Meta(type):
... foo = 'bar'
...
>>> class Foo(metaclass=Meta):
... pass
...
>>> hasattr(Foo, 'foo')
True
>>> 'foo' in dir(Foo)
False
最后但并非最不重要的:
如果对象有一个名为__dir__()
方法,此方法将被调用并且必须返回属性列表。
这意味着hasattr()
和dir()
可以更广泛地中“发现”如果.__dir__()
法已经实施了什么属性上有所差异。
只要坚持hasattr()
。首先,它的速度更快,因为对属性的测试很便宜,因为这只是对一个或多个字典的成员测试。枚举所有字典密钥并在实例,类和基类之间进行合并会导致CPU成本高得多。
使用'hasattr'的一个缺点是它会触发属性执行,这可能是高成本的。在诸如Django'OneToOneField'关系的情况下,这甚至会触发数据库查询。我不认为有其他选择,是吗? –
@AugustoMen:您可以使用*特定于应用程序*的测试方法来查看存在的属性。例如,我确定Django有枚举字段的方法。 –