如何检查对象是否具有某些属性?例如:

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

如何在使用属性属性之前确定它是否具有属性属性?


当前回答

我建议避免这样做:

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

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

也许这种方法更好:

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

其他回答

您可以使用hasattr()检查Python中的对象或类是否具有属性。

例如,Person类如下所示:

class Person:
    greeting = "Hello"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def test(self):
        print("Test")

然后,可以对对象使用hasattr(),如下所示:

obj = Person("John", 27)
obj.gender = "Male"
print("greeting:", hasattr(obj, 'greeting'))
print("name:", hasattr(obj, 'name'))
print("age:", hasattr(obj, 'age'))
print("gender:", hasattr(obj, 'gender'))
print("test:", hasattr(obj, 'test'))
print("__init__:", hasattr(obj, '__init__'))
print("__str__:", hasattr(obj, '__str__'))
print("__module__:", hasattr(obj, '__module__'))

输出:

greeting: True
name: True
age: True
gender: True
test: True
__init__: True
__str__: True
__module__: True

而且,您还可以直接使用hasattr()作为类名,如下所示:

print("greeting:", hasattr(Person, 'greeting'))
print("name:", hasattr(Person, 'name'))
print("age:", hasattr(Person, 'age'))
print("gender:", hasattr(Person, 'gender'))
print("test:", hasattr(Person, 'test'))
print("__init__:", hasattr(Person, '__init__'))
print("__str__:", hasattr(Person, '__str__'))
print("__module__:", hasattr(Person, '__module__'))

输出:

greeting: True
name: False
age: False
gender: False
test: True
__init__: True
__str__: True
__module__: True

正如贾雷特·哈迪回答的那样,哈沙特会做这个把戏。不过,我想补充一点,Python社区中的许多人建议采用“请求宽恕比请求许可更容易”(EAFP)而不是“三思而后行”(LBYL)的策略。参见以下参考文献:

EAFP vs LBYL(Re:到目前为止有点失望)EAFP与LBYL@代码如蟒蛇:惯用Python

ie:

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

…优先于:

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

对于字典以外的对象:

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

对于字典,hasattr()将不起作用。

许多人都在告诉字典使用has_key(),但它已经贬值了。因此,对于字典,必须使用has_attr()

if a.has_attr('property'):
    a['property']
 

或者您也可以使用

if 'property' in a:

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

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

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

然而,我不确定目前哪种方法是最好的。使用hasattr()、getattr(()或in。欢迎评论。

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

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