如何知道对象在 Python 中是否具有属性

Python 中是否有一种方法可以确定对象是否具有某些属性?例如:

>>> a = SomeClass()
>>> a.someProperty = value
>>> a.property
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: SomeClass instance has no attribute 'property'

使用前如何知道a是否具有 attribute property

答案

试试hasattr()

if hasattr(a, 'property'):
    a.property

编辑:请参阅以下zweiterlinde 的回答 ,他为寻求宽恕提供了很好的建议!一个非常 pythonic 的方法!

python 中的一般做法是,如果大多数情况下该属性很可能存在,则只需对其进行调用并允许该异常传播,或者使用 try / except 块捕获该属性。这可能比hasattr更快。如果该属性在大多数时间可能不存在,或者您不确定,使用hasattr可能比重复陷入异常块要快。

正如Jarret Hardie回答的那样, hasattr可以解决问题。不过,我想补充一点,Python 社区中的许多人都建议一种策略:“更容易要求宽恕而不是允许”(EAFP),而不是 “三思而后行”(LBYL)。请参阅以下参考:

EAFP vs LBYL(当时:到目前为止有点失望)
EAFP 与 LBYL @Code 像 Pythonista 一样:惯用的 Python

即:

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

... 优先于:

if hasattr(a, 'property'):
    doStuff(a.property)
else:
    otherStuff()

您可以使用hasattr()或 catch AttributeError ,但是如果您确实只想使用默认值(如果不存在默认值),最好的选择就是使用getattr()

getattr(a, 'property', 'default value')

我认为您正在寻找的是hasattr 。但是,如果您要检测python 属性 ,我建议使用类似的方法 -

try:
    getattr(someObject, 'someProperty')         
except AttributeError:
    print "Doesn't exist"
else
    print "Exists"

此处的缺点是还捕获了属性__get__代码中的属性错误。

否则,请 -

if hasattr(someObject, 'someProp'):
    #Access someProp/ set someProp
    pass

文件: http//docs.python.org/library/functions.html
警告:
我建议的原因是 hasattr 不会检测属性。
链接: http//mail.python.org/pipermail/python-dev/2005-December/058498.html

根据 pydoc,hasattr(obj,prop)只是调用 getattr(obj,prop)并捕获异常。因此,使用 try 语句包装属性访问并捕获 AttributeError 就像预先使用 hasattr()一样有效。

a = SomeClass()
try:
    return a.fake_prop
except AttributeError:
    return default_value

我建议避免这种情况:

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

用户 @jpalecek 提到了这一点:如果在doStuff()内部发生AttributeError则会迷路。

也许这种方法更好:

try:
    val = a.property
except AttributeError:
    otherStuff()
else:
    doStuff(val)

根据情况,您可以使用isinstance检查您拥有哪种对象,然后使用相应的属性。随着 Python 2.6 / 3.0 中抽象基类的引入,这种方法也变得更加强大(基本上,ABC 允许使用更复杂的鸭子输入方式)。

这是有用的一种情况是,如果两个不同的对象具有名称相同但含义不同的属性。仅使用hasattr可能会导致奇怪的错误。

一个很好的例子是迭代器和可迭代器之间的区别(请参阅问题)。迭代器和 Iterable 中的__iter__方法具有相同的名称,但在语义上完全不同!因此hasattr是没有用的,但是isinstance与 ABC 一起提供了一个干净的解决方案。

但是,我同意在大多数情况下, hasattr方法(在其他答案中进行了描述)是最合适的解决方案。

希望您期望使用 hasattr(),但要避免使用 hasattr(),请优先使用 getattr()。 getattr()比 hasattr()更快

使用 hasattr():

if hasattr(a, 'property'):
     print a.property

同样在这里我使用 getattr 获取属性,如果没有属性,则不返回

property = getattr(a,"property",None)
    if property:
        print property

编辑 :这种方法有严重的局限性。如果对象是可迭代对象,它应该可以工作。请检查以下评论。

如果您像我一样使用Python 3.6或更高版本,可以使用一种方便的替代方法来检查对象是否具有特定的属性:

if 'attr1' in obj1:
    print("attr1 = {}".format(obj1["attr1"]))

但是,我不确定哪种方法是目前最好的方法。使用hasattr()getattr()in 。欢迎发表评论。

这是一种非常直观的方法:

if 'property' in dir(a):
    a.property