赞
踩
如何确定对象是否具有某些属性?例如:
>>> a = SomeClass()
>>> a.property
Traceback (most recent call last):
File "", line 1, in
AttributeError: SomeClass instance has no attribute 'property'
在使用之前如何判断 a 是否具有属性 property?
HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com
试试 hasattr():
if hasattr(a, 'property'):
a.property
请参阅下面的 zweiterlinde’s answer,谁提供了关于请求宽恕的好建议!一个非常pythonic的方法!
python 中的一般做法是,如果该属性可能大部分时间都存在,只需调用它并让异常传播,或者使用 try/except 块捕获它。这可能会比 hasattr 快。如果该属性可能大部分时间都不存在,或者您不确定,则使用 hasattr 可能比反复陷入异常块更快。
似乎也在检查命名空间中的函数,例如:import string hasattr(string, "lower")
hasattr 与使用 try/except AttributeError 完全相同:hasattr 的文档字符串(在 Python 2.7 中)表示它使用 getattr 手动捕获异常。
@JeffTratner:很遗憾,hasattr 与 Python 2.x 中的 try: ... except AttributeError: 并不完全相同,因为 hasattr 将捕获所有异常。有关示例和简单的解决方法,请参阅 my answer。
如果您的对象是“dict”,则 hasattr 不起作用。在这些情况下使用 operator 或 haskey 方法。
可以为 self 的属性完成吗?像对象创建的 __init__() 内的 if not hasattr(self, 'property')
huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求
正如 Jarret Hardie 回答的那样,hasattr 可以解决问题。不过,我想补充一点,Python 社区中的许多人建议采用“更容易请求宽恕而不是许可”(EAFP)而不是“在跳跃之前先看”(LBYL)的策略。请参阅这些参考资料:
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()
…首选:
if hasattr(a, 'property'):
doStuff(a.property)
else:
otherStuff()
但是如何检查导致 AttributeError 的是 a.property,而不是 doStuff() 中的某个东西?看来你没有。我认为请求原谅真的很容易,但很多时候,它也是不正确的。
EAFP 似乎……疯了。 HasAttr 向未来的维护程序员电报您正在检查特定属性。获得异常不会告诉未来的程序员任何事情,并且可能会导致某人陷入困境。
@e5:在这种情况下你有一个公平的观点,但在许多情况下 EAFP 是唯一正确的选择。例如,如果您检查文件是否存在,然后打开它,期望它肯定存在,那么您的代码是错误的:文件可能在检查和使用之间被删除或重命名。这称为 TOCTOU 错误(Time-Of-Check-To-Time-Of-Use),除了导致崩溃之外,还可能是安全漏洞的来源。
@EthanHeilman 只有在异常来源有歧义时才会发疯,在大多数情况下,通过良好的设计可以避免这种情况。 try / except / finally 中的分层逻辑结构通常比使用对每段消费代码的抢先式 if 检查乱扔代码更健壮(程序员更不容易出错)逻辑。使错误也非常明确,并允许使用程序员直接处理它们。
这里的大多数模棱两可的抱怨仅仅是因为示例代码的结构很差。 try: 内的唯一内容应该是尝试的属性访问;也没有理由包装 doStuff 的执行。但仍有一些歧义的可能性:如果 property 是计算属性而不是普通属性,则其实现可能会在内部引发 AttributeError。这就是为什么在几乎所有像这样的实际情况下,getattr 都比 hasattr 或捕获 AttributeError 更可取。
huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!
您可以使用 hasattr() 或 catch AttributeError,但如果您真的只希望该属性的值没有默认值,那么最好的选择就是使用 getattr():
getattr(a, 'property', 'default value')
这解决了上述两个问题:a)可能的 AttributeError 来源的模糊性,b)保留 EAFP 方法。
它也是代码行数的 25%。当然,这必须是最好的解决方案。
这是最好的解决方案,“如果您真的只希望属性的值具有默认值”。虽然我相信这是许多人说他们想要检测属性是否存在时真正想要的,但 OP 实际上要求后者,因此将该问题的直接答案(hasattr,AttributeError)列在更高的位置是合理的.
赞成提到“默认属性”。有几次我需要这个,但忘记了!
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会
我认为您正在寻找的是 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
hasattr 通常可以很好地检测属性。只是它将在 property 包装的函数中引发异常视为不存在此类属性;链接的 Python 邮件列表帖子是关于在您尝试访问它时引发异常的属性。出于所有实际目的,所述属性不存在,因为它永远不会产生值。此外,hasattr 仅在 Py 3.1 及更早版本中抑制一般异常;在 3.2+ 中,它只抑制(替换为 False 返回)AttributeError。
huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。
根据 pydoc, hasattr(obj, prop) 只需调用 getattr(obj, prop) 并捕获异常。因此,使用 try 语句包装属性访问并捕获 AttributeError 与预先使用 hasattr() 一样有效。
a = SomeClass()
try:
return a.fake_prop
except AttributeError:
return default_value
那么 hasattr 实际上可能会被优化。例如与 pypy。
+1。当 SomeClass 覆盖 __getattr__ 时,这甚至比使用 hasattr更安全,因为 hasattr 将捕获 Python 2.x 中的所有异常,而不仅仅是 AttributeError就像你期望的那样。这已在 Python 3.2 中修复 — 请参阅 my other answer 了解简单的解决方法。
保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com
我想建议避免这种情况:
try:
doStuff(a.property)
except AttributeError:
otherStuff()
用户 @jpalecek 提到它:如果 AttributeError 出现在 doStuff() 中,你就迷路了。
也许这种方法更好:
try:
val = a.property
except AttributeError:
otherStuff()
else:
doStuff(val)
huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。
编辑:这种方法有严重的局限性。如果对象是可迭代的,它应该可以工作。请检查下面的评论。
如果您像我一样使用 Python 3.6 或更高版本,则有一个方便的替代方法来检查对象是否具有特定属性:
if 'attr1' in obj1:
print("attr1 = {}".format(obj1["attr1"]))
但是,我不确定哪个是目前最好的方法。使用 hasattr()、使用 getattr() 或使用 in。欢迎评论。
in 关键字用于检查可迭代类型。例如,'foo' in None 会引发错误 TypeError: argument of type 'NoneType' is not iterable。修复方法是在使用 in 之前检查类型是否可迭代。在纠正了不可迭代类型等边缘情况后,您最好使用 hasattr(),因为它旨在处理边缘情况。
这与属性访问无关。我不知道它是如何获得投票的。它与属性访问的唯一相似之处是,如果您使用 dict 作为“轻量级对象”,类似于 JavaScript 对象的设计,但大多数普通类通常不支持这一点(获取关于错误的变体@SethDifley)。
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会
hasattr() 是正确答案。我要补充的是,hasattr() 也可以很好地与 assert 结合使用(以避免不必要的 if 语句并使代码更具可读性):
assert hasattr(a, 'property'), 'object lacks property'
print(a.property)
如果缺少该属性,程序将退出并显示 AssertionError 并打印出提供的错误消息(在本例中为 object lacks property)。
如另一个 answer on SO 所述:
断言应该用于测试不应该发生的情况。目的是在程序状态损坏的情况下尽早崩溃。
这通常是缺少某个属性然后 assert 非常合适的情况。
这很有帮助,但可能并非总是如此。也许我想测试对象是否具有属性,然后第一次添加它,或者我必须为具有该属性的对象运行不同的代码。当代码无法继续时,断言可能会很好。但同样,情况并非总是如此。重要的是使用 hasattr 而不是周围的代码。
huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。
根据情况你可以用isinstance检查你有什么样的对象,然后使用相应的属性。随着在 Python 2.6/3.0 中引入 abstract base classes,这种方法也变得更加强大(基本上 ABC 允许更复杂的鸭子类型)。
一种有用的情况是,如果两个不同的对象具有同名但含义不同的属性。仅使用 hasattr 可能会导致奇怪的错误。
一个很好的例子是迭代器和可迭代对象之间的区别(参见 this 问题)。迭代器和可迭代对象中的 iter 方法名称相同,但语义完全不同!所以 hasattr 是无用的,但 isinstance 与 ABC 一起提供了一个干净的解决方案。
但是,我同意在大多数情况下,hasattr 方法(在其他答案中描述)是最合适的解决方案。
huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。
希望你期待 hasattr(),但尽量避免 hasattr(),请更喜欢 getattr()。 getattr() 比 hasattr() 快
使用 hasattr():
if hasattr(a, 'property'):
print a.property
同样在这里我使用 getattr 来获取属性,如果没有属性它返回 none
property = getattr(a,"property",None)
if property:
print property
getattr() is faster than hasattr(),您能对此发表评论吗?为什么更快?
@Groosha 有很多事情,为了简单起见,hasattr() 内部必须调用 getattr() 来执行它们的操作,所以我们可以直接使用 getattr() 检查这个docs.python.org/3/library/functions.html#hasattr,而不是调用多个方法
但是,如果该属性确实存在并且其值为 False,则您最终可能会误报。
huntsbot.com – 高效赚钱,自由工作
对于字典以外的对象:
if hasattr(a, 'property'):
a.property
对于字典,hasattr() 不起作用。
许多人告诉使用 has_key() 作为字典,但它已被贬值。所以对于字典,你必须使用 has_attr()
if a.has_attr('property'):
a['property']
对于 dict,使用 if 'property' in a:
HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。