问题:如何知道对象在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
回答 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
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
然后给出布尔值True
或False
根据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.