is there to Python的方式确定对象的属性,如果安has some?for example:P></
1 2 3 4 5 6
| >>> 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' |
你怎么能告诉如果ahas the propertybefore using属性页?P></
hasattr()试试:
1 2
| if hasattr(a, 'property'):
a.property |
编辑:看下面的答案zweiterlinde提供好的建议,我们forgiveness问谁!方法超Python!
一般的做法是,在Python中,如果房地产可能会有一大部分时间,与简单的呼叫它或者让它与异常propagate陷阱,或尝试/除块。这可能会比hasattr更快。如果属性是不可能在那里的大部分时间,或你不确定,可能会被利用hasattr更快比降到repeatedly异常块。
- 似乎也在检查命名空间中的函数,例如:import string hasattr(string,"lower")。
- hasattr与使用try/except AttributeError完全相同:hasattr的docstring(在python 2.7中)说它使用getattr hand捕获异常。
- 我认为最明显的用例与宽恕无关,它是"如果不存在就初始化它"的懒惰初始化。在源代码中同时进行初始化和使用通常比在一个位置初始化和在另一个位置使用要好。
- @Jefftratner:hasattr与python 2.x中的try: ... except AttributeError:并不完全相同,因为hasattr会捕获所有异常。请参阅我的答案,以获得一个示例和一个简单的解决方法。
- @马丁盖斯勒很有道理——这和它捕获所有异常的情况不同。不确定哪个版本更正确——这实际上取决于您所使用的假设以及谁在调用您的函数。谢谢你的澄清。
- 如果你理解的话,如[a.property for a in list_of_as if hasattr(a,"property")],hasattr也是最好的选择。
哈迪的hasattr贾勒特说,威尔的戏法。我想添加,虽然在Python社区,这是许多战略"的建议更容易就让forgiveness)比(E(AFP)"而不是"看在你跳"(lbyl)。这些参考文献:国有企业
lbyl(E(AFP):是再小disappointed为止)E(AFP)lbyl @样idiomatic pythonista:Python代码
即:
1 2 3 4
| try:
doStuff(a.property)
except AttributeError:
otherStuff() |
…………………优先考虑:
1 2 3 4
| if hasattr(a, 'property'):
doStuff(a.property)
else:
otherStuff() |
- 但如何检查导致attributeError的是a.property,而不是dostuff()中的某个属性?似乎你没有。我觉得请求原谅真的很容易,但很多时候,这也是不正确的。
- EAFP似乎…精神错乱。hasattr电报给未来的维护程序员,您正在检查一个特定的属性。获得一个异常不会告诉未来的程序员任何事情,也可能导致某人陷入困境。
- @E5:在这种情况下,你有一个公平的观点,但在许多情况下,EAFP是唯一正确的选择。例如,如果检查某个文件是否存在,然后打开它,希望它确实存在,那么您的代码就不正确:该文件可能在检查和使用之间被删除或重命名。这被称为toctou错误(检查时间到使用时间),除了造成崩溃之外,还可能是安全漏洞的来源。
- @Zweiterlinde,很棒的帖子,第一个链接不再有效。你能再提供一个吗?
- @我更新了链接
- @伊桑海尔曼只有在例外的来源有歧义的时候才是疯狂的,这在大多数情况下可以通过良好的设计避免。Try/Except/Finally中逻辑的良好分层结构通常比使用抢占式if检查每段消耗的代码浪费代码更健壮(不太容易出现程序员错误)。使错误也非常明确,并允许使用户程序员选择直接处理它们。
- + 1。好极了,+很棒的链接!第一次听说伟大的埃多克斯(19岁)(那是她)!女性在计算方面永远是正当的。
- 这不是断言的理想用例吗?
- 这里的大多数歧义抱怨仅仅是因为示例代码的结构不好。try:中唯一的东西应该是尝试的属性访问;也没有理由包装doStuff的执行。但是,仍然存在一些模糊性:如果property是一个计算属性而不是一个普通属性,那么它的实现可能会在内部引发AttributeError。这就是为什么在几乎所有实际情况下,getattr比hasattr或捕获AttributeError更可取的原因。
- 这难道不是将异常用作信号逻辑(即流量控制)而不是它们应该用于的——导致错误的异常情况吗?
- @Scot异常不适用于Python中的异常情况,它们也不会给性能增加任何重要的开销。这就是为什么EAFP更受欢迎的原因。如果与if-else结构相比,这会掩盖逻辑,则取决于上下文。
- @史考特:先停三个字:例外情况是特殊情况。这些异常情况是否会导致概念上的错误并不重要;关键是您可以不间断地编写"正常"控制流,并处理"异常"情况(有异常)。
- 如果你想检查if self.thread1:,这个模式会很奇怪…try变得毫无意义。
- lbyl通常比eafp更简洁。考虑:join_xy(v.x if hasattr(v, 'x') else None, v.y if hasattr(v, 'y') else None),这比使用两个try...except块在join_xy语句(9行)中使用之前设置x和y变量更简单和更短(1行)。后者还创建了两个多余的变量,如果x或y是大的不可变值(10行),则应删除这些变量。
- 我有兴趣知道哪一个性能更好。我怀疑尝试除了会是,因为当代码工作时,您避免了额外的调用,但也许这取决于它是否在循环中,以及您是否希望它大部分通过,或者希望它大部分失败。没有额外的函数调用,python的速度就足够慢了。
- @nick异常处理程序的设置成本很低,但在发生异常时却非常昂贵,因此从性能上讲,最好仅在异常机会很少或测试和有效使用之间存在可能的竞争条件时才使用EAFP。
- 不管怎样,hasattr也有同样的问题:如果一个属性引发AttributeError,它会返回False。
- @Brunodesthuilliers在Python中不一定如此。我鼓励您使用带有显式提升的timeit,来分析异常处理程序的实际成本。在cpython或pypy中,我怀疑您会注意到与lbyl的区别很大(这是因为它基本上只是几个额外的函数调用;Exception及其子代在builtins中已经是一个别名,因此当您在lbyl中链接更多的函数调用时,您的性能将接近eafp)。
- 如果您所做的只是懒惰地在初始化器中加载一些耗时计算的内容,则Try-Except似乎有些过头了。
- -1不管标准是什么,这都是不好的做法。对于你正在做的事情和使用hasattr要明确得多,而不是草率地使用try,除非无处不在。
你可以使用AttributeErrorhasattr()或捕捉,但如果你真的只是想与默认值的属性,如果它是不是最好的选择是有,只是用getattr():
1
| getattr(a, 'property', 'default value') |
- 这解决了上述两个问题:a)可能的属性错误源的模糊性,b)保留EAFP方法。
- 这也是25%的代码行。当然,这必须是最好的解决办法。
- 这是最好的解决方案,"如果你真的只是想要一个默认属性的值。"虽然我相信这是很多人说他们想要检测一个属性是否存在时实际想要的,但是OP实际上要求后者,所以直接回答这个问题(hasattr,attributeerror)是合理的。上市更高。
- 但是hynek.me/articles/hasattr
你是我想找的是hasattr。然而,像这样的东西,我建议你要到Python的性能检测
1 2 3 4 5 6
| try:
getattr(someObject, 'someProperty')
except AttributeError:
print"Doesn't exist"
else
print"Exists" |
这里的缺点是,在__get__代码错误性质的属性也被抓住了。
此外,的
1 2 3
| if hasattr(someObject, 'someProp'):
#Access someProp/ set someProp
pass |
文档:http://docs.python.org /图书馆/ functions.html警告:那是我的推荐的原因是不是hasattr检测性能。链接:http://mail.python.org pipermail Python开发/ / / / 058498.html 2005年十二月
- 所以,你的建议是,不要自食其力——实施它!
- 好吧,不完全是,不要使用你想要检测属性的内置iff。否则,哈萨特就完美无缺了。
- hasattr检测属性一般都很好。它只是将在property包装函数中引发异常视为不存在此类属性;链接的python邮件列表post是一个属性,当您试图访问它时,它会引发异常。就所有实际目的而言,所述属性不存在,因为它永远不会产生值。另外,hasattr一般只抑制PY 3.1及更早版本的例外;在3.2+版本中,它只抑制(替换为False返回)AttributeError。
根据pydoc hasattr(obj,道具),简单的调用getattr(obj,道具)和捕获异常。所以,它是有效的,只是在对包的属性访问尝试和捕捉attributeerror语句与它使用的hasattr(前)。
1 2 3 4 5
| a = SomeClass()
try:
return a.fake_prop
except AttributeError:
return default_value |
- 好吧,hasattr实际上是可以优化的。例如PyPy。
- + 1。当SomeClass重写__getattr__时,这比使用hasattr更安全,因为hasattr将捕获python 2.x中的所有异常,而不仅仅是如您所料的AttributeError。这是在Python3.2中修复的——请参阅我的另一个简单解决方案。
我想这suggest避免:
1 2 3 4
| try:
doStuff(a.property)
except AttributeError:
otherStuff() |
"用户"一文jpalecek:如果它发生在你的AttributeErrordoStuff(),失落。
也许这是更好的方法。
1 2 3 4 5 6
| try:
val = a.property
except AttributeError:
otherStuff()
else:
doStuff(val) |
- 也可能只是:try: a.property不需要左手边
根据检查的情况下,你可以做什么,你有一个什么样的isinstance对象,然后使用相应的属性。摘要介绍基本的Python中的类/方法2.6 3.0,这也成为强大的,更大的(基本上允许更复杂的字母式的鸭打字)。
这是一个有用的情况是,如果两个不同的对象将有一个属性与相同的名称,但具有不同的意义。然后利用奇异hasattr只会导致错误。
一个很好的例子是迭代器和学习之间的区别(见这个问题)。该方法在__iter__迭代器和一个迭代变量相同的名称,但不同的是semantically地狱!操作系统hasattr是无用的,但isinstanceABC’s一起提供了清洁的解决方案。
然而,在大多数情况下,我同意在hasattr方法中描述的其他的答案是最合适的解决方案)。
希望你expecting hasattr(),但是试图避免hasattr getattr请选择()和()。getattr()是一hasattr(比)。
利用hasattr():
1 2
| if hasattr(a, 'property'):
print a.property |
它让我在这里使用getattr物业,如果物业没有它不返回
1 2 3
| property = getattr(a,"property",None)
if property:
print property |
编辑:这个方法有严重的局限性。它应该工作,如果一个对象是一个迭代变量。请检查下面的评论。
如果你是使用Python或高3.6样我有一个方便的替代CT检查是否有特定的属性:一个对象
1 2
| 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之前检查类型是否可Itable。在修正了像不可重类型这样的边缘情况之后,您最好使用hasattr(),因为它是为处理边缘情况而设计的。
- 这与属性访问无关。我不知道它是如何被否决的。它与属性访问的唯一相似之处是,如果您将dict用作"轻量级对象",类似于javascript对象的设计,但大多数普通类一般不支持这种情况(获取@sethdifley所提到错误的变体)。
- 如果"变量"在类中。?
这非常简单,只需使用dir(对象)。这将返回对象的每个可用函数和属性的列表。
您可以使用hasattr内置方法检查object是否包含属性。
例如,如果您的对象是a并且您想要检查属性stuff。
1 2 3 4 5 6 7
| >>> class a:
... stuff ="something"
...
>>> hasattr(a,'stuff')
True
>>> hasattr(a,'other_stuff')
False |
方法签名本身是hasattr(object, name) -> bool,这意味着如果object具有属性,该属性被传递给hasattr中的第二个参数,而根据对象中name属性的存在,它给出了布尔的True或False。