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

时间:2009-03-04 14:45:59

标签: python attributes

在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之前,如何判断property是否具有属性{{1}}?

16 个答案:

答案 0 :(得分:1913)

尝试hasattr()

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

编辑:请参阅下面的zweiterlinde's answer,他提供了有关请求宽恕的好建议!一种非常pythonic的方法!

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

答案 1 :(得分:548)

Jarret Hardie回答时,hasattr会做到这一点。不过,我想补充一点,Python社区中的许多人都建议采用“更容易请求宽恕而不是许可”(EAFP)的策略,而不是“在你跳跃之前先看”(LBYL)。请参阅以下参考资料:

EAFP vs LBYL (was Re: A little disappointed so far)
EAFP vs. LBYL @Code Like a Pythonista: Idiomatic Python

即:

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

...首选:

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

答案 2 :(得分:421)

您可以使用hasattr()或捕获AttributeError,但如果您确实希望该属性的值具有默认值(如果不存在),则最佳选择就是使用{{1 }}:

getattr()

答案 3 :(得分:36)

我认为你要找的是 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

答案 4 :(得分:28)

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

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

答案 5 :(得分:22)

我想建议避免这个:

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

用户@jpalecek提到它:如果AttributeError内发生doStuff(),您就会丢失。

也许这种方法更好:

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

答案 6 :(得分:12)

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

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

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

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

答案 7 :(得分:10)

希望你期待hasattr(),但是尽量避免使用hasattr(),请更喜欢getattr()。 getattr()比hasattr()

更快

使用hasattr():

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

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

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

答案 8 :(得分:9)

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

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

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

但是,我不确定现在哪种方法最好。使用hasattr(),使用getattr()或使用in。欢迎提出意见。

答案 9 :(得分:1)

hasattr()是正确的答案。我要补充的是,hasattr()也可以与assert结合使用(以避免不必要的if语句,并使代码更具可读性):

assert hasattr(a, 'property'), 'object lacks property' 

如另一个answer on SO中所述:应当使用断言来测试永远不会发生的条件。目的是在程序状态损坏的情况下尽早崩溃。

答案 10 :(得分:0)

您可以使用object内置方法来检查hasattr是否包含属性。

对于一个实例,如果您的对象是a,并且您要检查属性stuff

>>> class a:
...     stuff = "something"
... 
>>> hasattr(a,'stuff')
True
>>> hasattr(a,'other_stuff')
False

方法签名本身为hasattr(object, name) -> bool,这意味着如果object具有属性,并且该属性传递给hasattr中的第二个参数,而不是布尔值{{1} }或True,具体取决于对象中False属性的存在。

答案 11 :(得分:0)

这非常简单,只需使用dir( object )
这将返回对象的每个可用功能和属性的列表。

答案 12 :(得分:0)

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

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

答案 13 :(得分:0)

另一个可能的选择,但这取决于您是否表示之前

undefined = object()

class Widget:

    def __init__(self):
        self.bar = 1

    def zoom(self):
        print("zoom!")

a = Widget()

bar = getattr(a, "bar", undefined)
if bar is not undefined:
    print("bar:%s" % (bar))

foo = getattr(a, "foo", undefined)
if foo is not undefined:
    print("foo:%s" % (foo))

zoom = getattr(a, "zoom", undefined)
if zoom is not undefined:
    zoom()

输出:

bar:1
zoom!

这甚至可以检查无值属性。

但是!请务必小心,不要意外地实例化和比较多个地方的undefined,因为在这种情况下is永远不会起作用。

答案 14 :(得分:0)

对于字典以外的对象:

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

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

许多人告诉使用 has_key() 作为字典,但它已贬值。 所以对于字典,你必须使用 has_attr()

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

答案 15 :(得分:-1)

需要注意的是,如果您所指的对象是“dict”,则 hasattr 不起作用。

hasattr 不测试字典的成员。改用 in 运算符,或 has_key 方法

d = {'a': 1}
d.has_key('a') #True
'a' in d #True