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

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

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


尝试hasattr():

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

请看下面zweiterlinde的回答,他提供了关于请求宽恕的好建议!一个非常蟒蛇的方法!

python中的一般做法是,如果属性大部分时间都可能存在,那么只需调用它,让异常传播,或者用try/except块捕获它。这可能比hasattr更快。如果属性可能在大多数时间都不存在,或者您不确定,那么使用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

正如贾雷特·哈迪回答的那样,哈沙特会做这个把戏。不过,我想补充一点,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()

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

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

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

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


您可以使用hasattr()或catch AttributeError,但如果您真的只希望属性的值具有默认值(如果不存在),最好的选择就是使用getattr(

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

我建议避免这样做:

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

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

也许这种方法更好:

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

希望您希望使用hasattr(),但尽量避免使用hasattr(),请选择getattr(。getattr()比hasttr()快

使用hasattr():

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

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

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

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

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

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

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


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

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

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

方法签名本身是hasattr(object,name)->bool,这意味着如果对象具有传递给hasattr中的第二个参数的属性,则根据对象中name属性的存在,它会给出布尔值True或False。


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


这里有一个非常直观的方法:

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

如果a是字典,您可以正常检查

if 'property' in a:
    a.property

另一种可能的选择,但这取决于您之前的意思:

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!

这甚至允许您检查无值属性。

但是要非常小心,不要意外地实例化和比较未定义的多个位置,因为在这种情况下is永远不会工作。

更新:

由于我在上面的段落中警告过,有多个从未匹配的未定义,我最近稍微修改了这个模式:

undefined=未实现

NotImplemented(不要与NotImplementedError混淆)是一个内置的:它与JS undefined的意图半匹配,您可以在任何地方重用它的定义,并且它总是匹配的。缺点是它在布尔值中是“真实的”,在日志和堆栈跟踪中看起来很奇怪(但当你知道它只出现在这个上下文中时,你很快就会忘记它)。


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

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

如果缺少属性,程序将退出并显示AssertionError,并打印出提供的错误消息(在这种情况下,对象缺少属性)。

如SO的另一份答复所述:

断言应该用于测试不应该发生的条件。目的是在程序状态损坏的情况下尽早崩溃。

通常情况下,如果缺少属性,那么断言是非常合适的。


对于字典以外的对象:

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

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

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

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

或者您也可以使用

if 'property' in a:

您可以使用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