在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()