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

问题:如何知道对象在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属性property之前,如何判断该属性是否具有?

Is there a way in Python to determine if an object has some attribute? For example:

>>> 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'

How can you tell if a has the attribute property before using it?


回答 0

尝试hasattr()

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

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

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

Try hasattr():

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

EDIT: See zweiterlinde’s answer below, who offers good advice about asking forgiveness! A very pythonic approach!

The general practice in python is that, if the property is likely to be there most of the time, simply call it and either let the exception propagate, or trap it with a try/except block. This will likely be faster than hasattr. If the property is likely to not be there most of the time, or you’re not sure, using hasattr will probably be faster than repeatedly falling into an exception block.


回答 1

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

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

即:

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

…优先于:

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

As Jarret Hardie answered, hasattr will do the trick. I would like to add, though, that many in the Python community recommend a strategy of “easier to ask for forgiveness than permission” (EAFP) rather than “look before you leap” (LBYL). See these references:

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

ie:

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

… is preferred to:

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

回答 2

您可以使用hasattr()或catch AttributeError,但是如果您确实只想使用带有缺省值的属性值(如果该值不存在),最好的选择就是使用getattr()

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

You can use hasattr() or catch AttributeError, but if you really just want the value of the attribute with a default if it isn’t there, the best option is just to use getattr():

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

回答 3

我认为您正在寻找的是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

I think what you are looking for is hasattr. However, I’d recommend something like this if you want to detect python properties

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

The disadvantage here is that attribute errors in the properties __get__ code are also caught.

Otherwise, do-

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

Docs:http://docs.python.org/library/functions.html
Warning:
The reason for my recommendation is that hasattr doesn’t detect properties.
Link:http://mail.python.org/pipermail/python-dev/2005-December/058498.html


回答 4

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

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

According to pydoc, hasattr(obj, prop) simply calls getattr(obj, prop) and catches exceptions. So, it is just as valid to wrap the attribute access with a try statement and catch AttributeError as it is to use hasattr() beforehand.

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

回答 5

我建议避免这种情况:

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

用户@jpalecek提到了它:如果在AttributeError内部发生doStuff(),那么您会迷路。

也许这种方法更好:

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

I would like to suggest avoid this:

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

The user @jpalecek mentioned it: If an AttributeError occurs inside doStuff(), you are lost.

Maybe this approach is better:

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

回答 6

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

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

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

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

Depending on the situation you can check with isinstance what kind of object you have, and then use the corresponding attributes. With the introduction of abstract base classes in Python 2.6/3.0 this approach has also become much more powerful (basically ABCs allow for a more sophisticated way of duck typing).

One situation were this is useful would be if two different objects have an attribute with the same name, but with different meaning. Using only hasattr might then lead to strange errors.

One nice example is the distinction between iterators and iterables (see this question). The __iter__ methods in an iterator and an iterable have the same name but are semantically quite different! So hasattr is useless, but isinstance together with ABC’s provides a clean solution.

However, I agree that in most situations the hasattr approach (described in other answers) is the most appropriate solution.


回答 7

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

使用hasattr():

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

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

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

Hope you expecting hasattr(), but try to avoid hasattr() and please prefer getattr(). getattr() is faster than hasattr()

using hasattr():

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

same here i am using getattr to get property if there is no property it return none

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

回答 8

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

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

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

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

EDIT:This approach has serious limitation. It should work if the object is an iterable one. Please check the comments below.

If you are using Python 3.6 or higher like me there is a convenient alternative to check whether an object has a particular attribute:

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

However, I’m not sure which is the best approach right now. using hasattr(), using getattr() or using in. Comments are welcome.


回答 9

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

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

Here’s a very intuitive approach :

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

回答 10

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

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

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

方法签名本身是hasattr(object, name) -> bool指是否object具有传递给第二个参数的属性hasattr然后给出布尔值TrueFalse根据name对象中属性的存在。

You can check whether object contains attribute by using hasattr builtin method.

For an instance if your object is a and you want to check for attribute stuff

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

The method signature itself is hasattr(object, name) -> bool which mean if object has attribute which is passed to second argument in hasattr than it gives boolean True or False according to the presence of name attribute in object.


回答 11

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

This is super simple, just use dir(object)
This will return a list of every available function and attribute of the object.


回答 12

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

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在这种情况下,将永远无法工作。

更新:

由于我在上一段中警告过,具有多个从未匹配的未定义,因此我最近对这种模式进行了一些修改:

undefined = NotImplemented

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

Another possible option, but it depends if what you mean by before:

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()

output:

bar:1
zoom!

This allows you to even check for None-valued attributes.

But! Be very careful you don’t accidentally instantiate and compare undefined multiple places because the is will never work in that case.

Update:

because of what I was warning about in the above paragraph, having multiple undefineds that never match, I have recently slightly modified this pattern:

undefined = NotImplemented

NotImplemented, not to be confused with NotImplementedError, is a built-in: it semi-matches the intent of a JS undefined and you can reuse its definition everywhere and it will always match. The drawbacks is that it is “truthy” in booleans and it can look weird in logs and stack traces (but you quickly get over it when you know it only appears in this context).


回答 13

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

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

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

hasattr() is the right answer. What I want to add is that hasattr() can also be used well in conjunction with assert (to avoid unnecessary if statements and make the code more readable):

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

As stated in another answer on SO: Asserts should be used to test conditions that should never happen. The purpose is to crash early in the case of a corrupt program state.