在Python中,这是一个好的实践吗?
(在不使用它的情况下检查这样的属性是否明智?更新: 如果您真的只对属性在Python中,这是一个好的实践吗?,python,Python,(在不使用它的情况下检查这样的属性是否明智?更新: 如果您真的只对属性foo是否存在感兴趣(并且不使用该属性做任何事情),那么当然hasattr()可能是检查该属性的更好方法。 从开发人员/用户的角度来看,我必须承认,对我来说,hasattr()的使用更好地反映了您的意图。除此之外,它还将减少代码: try: spam.foo except AttributeError: do_somthing() hasattr()的文档描述了它是通过以下方式实现的: (这是通过调用geta
foo
是否存在感兴趣(并且不使用该属性做任何事情),那么当然hasattr()
可能是检查该属性的更好方法。从开发人员/用户的角度来看,我必须承认,对我来说,
hasattr()
的使用更好地反映了您的意图。除此之外,它还将减少代码:
try:
spam.foo
except AttributeError:
do_somthing()
hasattr()
的文档描述了它是通过以下方式实现的:
(这是通过调用getattr(object,name)
并查看它是否引发异常来实现的
因此,基本上,hasattr()
的操作与您的操作完全相同。在这种情况下,我肯定会使用内置解决方案,即hasattr()
。你不会获得任何速度优势
Python鼓励: 请求原谅比得到允许容易 因此,是的,如果你或多或少知道
垃圾邮件在大多数情况下都会有foo
属性(代码会(稍微)快一些),那么这正是你应该做的。
否则,如果spam
没有foo
属性(大多数情况下),那么这种方法会更好:
if not hasattr(spam,'foo'):
do_something()
我链接到的维基百科部分描述了这一点。Quote(其中EAFP版本指的是您编写代码示例的方式):
这两个代码示例具有相同的效果,但会有性能差异。当垃圾邮件具有属性eggs时,EAFP样本将运行得更快。当垃圾邮件没有属性eggs(“例外”情况)时,EAFP样本将运行较慢。(…)如果例外情况很少,则EAFP版本的平均性能将优于替代版本
这在某种程度上是显而易见的,因为(使用EAFP)在想要访问属性之前,不必每次都反省对象。更好地使用
if hasattr(spam, 'foo'):
bar = spam.foo
else:
do_somthing()
Python文档:
hasattr(对象、名称)
参数是一个对象和一个字符串。如果
字符串是其中一个
对象的属性,否则为False。
(这是通过调用
getattr(对象、名称)和
它是否引发异常或
没有。)
如果您想检查spam.foo
,可以使用hasattr(spam,“foo”)
hasattr(spam,foo)
假设foo
是一个包含字符串的变量,并检查spam
中由字符串命名的属性。+1表示答案。我选择了费利克斯的答案,因为如果一个访问者发现了这个问题,我认为他们理解这两个角度是很重要的。他的回答现在不再是“使用哪个?”而更多的是“使用界面来表现风格,或者使用实现来提高速度?”@orokusaki:我再次更新了我的答案。您的代码正是hasattr
的实现方式(我现在注意到了这一点)。所以我会选择hasattr,因为你可能无法获得可测量的速度优势。@orokusaki这正是我所想的:)并且已经给出了felix+1来考虑这两个角度@felix在我的案例中仍然是这样吗(在“try”上下文中我根本没有使用属性)?它仍然被认为是Pythonic吗?我认为try…catch
是个坏主意。如果可以,尽量避免使用它们,即使请求原谅比允许更容易
@orokusaki:如果不使用属性,为什么要这样做?如果您正在测试它是什么类型的对象,那么不,这不被认为是Pythonic。相反,以您希望的方式使用对象并处理由此产生的任何异常是很典型的。更好的方法是,检查为什么您有一个函数可以接受具有不同接口的各种对象。这是一个更高阶的函数,用于检查属性是否存在,并在未设置属性时更改函数。如果属性是属性,并且属性有副作用,则这可能是灾难性的。为什么您需要知道某个属性是否存在?你有消息来源。为什么不读源代码?
if hasattr(spam,"foo"):
#dosomthing with spam.foo
else:
do_somthing()