Luc*_*hez 1491 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'
Run Code Online (Sandbox Code Playgroud)
在使用之前如何判断是否a具有该属性property?
Jar*_*die 2114
试试hasattr():
if hasattr(a, 'property'):
a.property
Run Code Online (Sandbox Code Playgroud)
编辑:请参阅下面的zweiterlinde的答案,谁提供了关于请求宽恕的好建议!一种非常pythonic的方法!
python中的一般做法是,如果属性可能在大多数时间都存在,只需调用它并让异常传播,或者使用try/except块捕获它.这可能会比hasattr.如果该属性可能在大多数时间不存在,或者您不确定,使用hasattr可能会比重复进入异常块更快.
zwe*_*nde 581
正如Jarret Hardie回答的那样,hasattr会做到这一点.不过,我想补充一点,Python社区中的许多人都建议采用"更容易请求宽恕而不是许可"(EAFP)的策略,而不是"在你跳跃之前先看"(LBYL).见这些参考文献:
EAFP vs LBYL(Re:有点失望)
EAFP vs. LBYL @Code就像Pythonista:惯用语Python
即:
try:
doStuff(a.property)
except AttributeError:
otherStuff()
Run Code Online (Sandbox Code Playgroud)
...优先:
if hasattr(a, 'property'):
doStuff(a.property)
else:
otherStuff()
Run Code Online (Sandbox Code Playgroud)
Car*_*yer 444
你可以使用hasattr()或者捕获AttributeError,但是如果你真的只想要属性的值,如果它不存在,那么最好的选择就是使用getattr():
getattr(a, 'property', 'default value')
Run Code Online (Sandbox Code Playgroud)
bat*_*rat 40
我认为你要找的是hasattr.但是,如果你想检测python属性,我会推荐这样的东西-
try:
getattr(someObject, 'someProperty')
except AttributeError:
print "Doesn't exist"
else
print "Exists"
Run Code Online (Sandbox Code Playgroud)
这里的缺点是属性__get__代码中的属性错误也被捕获.
否则,做 -
if hasattr(someObject, 'someProp'):
#Access someProp/ set someProp
pass
Run Code Online (Sandbox Code Playgroud)
文档:http://docs.python.org/library/functions.html
警告:
我推荐的原因是hasattr没有检测到属性.
链接:http://mail.python.org/pipermail/python-dev/2005-December/058498.html
Jor*_*wis 30
根据pydoc,hasattr(obj,prop)只需调用getattr(obj,prop)并捕获异常.因此,使用try语句包装属性访问并捕获AttributeError同样有效,因为它是事先使用hasattr().
a = SomeClass()
try:
return a.fake_prop
except AttributeError:
return default_value
Run Code Online (Sandbox Code Playgroud)
Mai*_*ico 23
我想建议避免这个:
try:
doStuff(a.property)
except AttributeError:
otherStuff()
Run Code Online (Sandbox Code Playgroud)
用户@jpalecek提到它:如果AttributeError内部发生doStuff(),你就会迷路.
也许这种方法更好:
try:
val = a.property
except AttributeError:
otherStuff()
else:
doStuff(val)
Run Code Online (Sandbox Code Playgroud)
F.M*_*.F. 23
hasattr()是正确的答案。我要补充的是,可以和asserthasattr()很好地结合使用(避免不必要的语句,让代码更具可读性):if
assert hasattr(a, 'property'), 'object lacks property'
print(a.property)
Run Code Online (Sandbox Code Playgroud)
如果缺少该属性,程序将退出并AssertionError打印出提供的错误消息(object lacks property在本例中)。
正如SO 的另一个答案中所述:
断言应该用于测试不应该发生的情况。目的是在程序状态损坏的情况下尽早崩溃。
通常情况下,当某个属性缺失但又assert非常合适时,就会出现这种情况。
Sha*_*shi 23
对于字典以外的对象:
if hasattr(a, 'property'):
a.property
Run Code Online (Sandbox Code Playgroud)
对于字典,hasattr()不起作用。
很多人都说用has_key()字典,但它已经贬值了。所以对于字典,你必须使用has_attr()
if a.has_attr('property'):
a['property']
Run Code Online (Sandbox Code Playgroud)
或者你也可以使用
if 'property' in a:
Run Code Online (Sandbox Code Playgroud)
nik*_*kow 12
根据具体情况,您可以检查isinstance您拥有的对象类型,然后使用相应的属性.随着Python 2.6/3.0 中抽象基类的引入,这种方法也变得更加强大(基本上ABCs允许更复杂的鸭子打字方式).
一种情况是,如果两个不同的对象具有相同名称但具有不同含义的属性,则这是有用的.仅使用hasattr可能会导致奇怪的错误.
一个很好的例子是迭代器和迭代器之间的区别(参见这个问题).将__iter__在迭代器和迭代方法具有相同的名称,但在语义上是完全不同的!所以hasattr没用,但isinstance与ABC一起提供了一个干净的解决方案.
但是,我同意在大多数情况下,这种hasattr方法(在其他答案中描述)是最合适的解决方案.
Jan*_*amu 11
希望你期待hasattr(),但尽量避免使用hasattr(),请更喜欢getattr().getattr()比hasattr()更快
使用hasattr():
if hasattr(a, 'property'):
print a.property
Run Code Online (Sandbox Code Playgroud)
同样在这里我使用getattr来获取属性,如果没有属性则返回none
property = getattr(a,"property",None)
if property:
print property
Run Code Online (Sandbox Code Playgroud)
nay*_*yak 10
编辑:这种方法有严重的局限性.如果对象是可迭代的,它应该工作.请查看以下评论.
如果您像我一样使用Python 3.6或更高版本,则有一个方便的替代方法来检查对象是否具有特定属性:
if 'attr1' in obj1:
print("attr1 = {}".format(obj1["attr1"]))
Run Code Online (Sandbox Code Playgroud)
但是,我不确定现在哪种方法最好.使用hasattr(),使用getattr()或使用in.欢迎评论.
Ale*_*ine 10
这是一个非常直观的方法:
if 'property' in dir(a):
a.property
Run Code Online (Sandbox Code Playgroud)
小智 6
在 Python 中,您可以使用hasattr()检查对象或类是否具有属性。
例如有如下所示的Person类:
class Person:
greeting = "Hello"
def __init__(self, name, age):
self.name = name
self.age = age
def test(self):
print("Test")
Run Code Online (Sandbox Code Playgroud)
然后,您可以对对象使用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__'))
Run Code Online (Sandbox Code Playgroud)
输出:
greeting: True
name: True
age: True
gender: True
test: True
__init__: True
__str__: True
__module__: True
Run Code Online (Sandbox Code Playgroud)
并且,您还可以直接使用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__'))
Run Code Online (Sandbox Code Playgroud)
输出:
greeting: True
name: False
age: False
gender: False
test: True
__init__: True
__str__: True
__module__: True
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
783917 次 |
| 最近记录: |