有没有办法在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楼
我想建议避免这个:
try:
doStuff(a.property)
except AttributeError:
otherStuff()
用户@jpalecek提到它:如果在doStuff()
内发生AttributeError
则会丢失。
也许这种方法更好:
try:
val = a.property
except AttributeError:
otherStuff()
else:
doStuff(val)
#2楼
希望你期待hasattr(),但尽量避免使用hasattr(),请更喜欢getattr()。 getattr()比hasattr()更快
使用hasattr():
if hasattr(a, 'property'):
print a.property
同样在这里我使用getattr来获取属性,如果没有属性则返回none
property = getattr(a,"property",None)
if property:
print property
#3楼
编辑 :这种方法有严重的局限性。 如果对象是可迭代的,它应该工作。 请查看以下评论。
如果您像我一样使用Python 3.6或更高版本,则有一个方便的替代方法来检查对象是否具有特定属性:
if 'attr1' in obj1:
print("attr1 = {}".format(obj1["attr1"]))
但是,我不确定现在哪种方法最好。 使用hasattr()
,使用getattr()
或使用in
。 欢迎评论。
#4楼
您可以使用hasattr
builtin方法检查object
是否包含属性。
对于一个实例,如果您的对象是a
并且您想要检查属性stuff
>>> class a:
... stuff = "something"
...
>>> hasattr(a,'stuff')
True
>>> hasattr(a,'other_stuff')
False
方法签名本身是hasattr(object, name) -> bool
,这意味着如果object
具有传递给hasattr
第二个参数的属性 ,则根据对象中name
属性的存在给出布尔值True
或False
。
#5楼
)
这很简单,只需使用dir(
)
这将返回对象的每个可用函数和属性的列表。
#6楼
这是一个非常直观的方法:
if 'property' in dir(a):
a.property
#7楼
另一种可能的选择,但这取决于你之前的意思:
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
绝不会在这种情况下工作。
#8楼
尝试hasattr()
:
if hasattr(a, 'property'):
a.property
编辑:请参阅下面的zweiterlinde的答案 ,谁提供了关于请求宽恕的好建议! 一种非常pythonic的方法!
python中的一般做法是,如果属性可能在大多数时间都存在,只需调用它并让异常传播,或者使用try / except块捕获它。 这可能会比hasattr
更快。 如果该属性很可能在大多数时间不存在,或者您不确定,使用hasattr
可能会比重复进入异常块更快。
#9楼
我认为你要找的是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
#10楼
根据pydoc,hasattr(obj,prop)只需调用getattr(obj,prop)并捕获异常。 因此,使用try语句包装属性访问并捕获AttributeError同样有效,因为它是事先使用hasattr()。
a = SomeClass()
try:
return a.fake_prop
except AttributeError:
return default_value
#11楼
正如Jarret Hardie回答的那样, hasattr
将会做到这一点。 不过,我想补充一点,Python社区中的许多人都建议采用“更容易请求宽恕而不是许可”(EAFP)的策略,而不是“在你跳跃之前先看”(LBYL)。 见这些参考文献:
EAFP对LBYL(Re:到目前为止有点失望)
EAFP vs. LBYL @Code就像一个Pythonista:惯用语
即:
try:
doStuff(a.property)
except AttributeError:
otherStuff()
...优先:
if hasattr(a, 'property'):
doStuff(a.property)
else:
otherStuff()
#12楼
根据具体情况,您可以查看isinstance
您拥有的对象类型,然后使用相应的属性。 随着Python 2.6 / 3.0中抽象基类的引入,这种方法也变得更加强大(基本上ABCs允许更复杂的鸭子打字方式)。
一种情况是,如果两个不同的对象具有相同名称但具有不同含义的属性,则这是有用的。 仅使用hasattr
可能会导致奇怪的错误。
一个很好的例子是迭代器和迭代器之间的区别(参见这个问题)。 迭代器和迭代中的__iter__
方法具有相同的名称,但在语义上完全不同! 所以hasattr
是无用的,但isinstance
与ABC的一起提供了一个干净的解决方案。
但是,我同意在大多数情况下, hasattr
方法(在其他答案中描述)是最合适的解决方案。
#13楼
你可以使用hasattr()
或catch AttributeError
,但如果你真的只想要属性的值,如果不存在,那么最好的选择就是使用getattr()
:
getattr(a, 'property', 'default value')