在Python中,这是一种好习惯吗?
try:
spam.foo
except AttributeError:
do_somthing()
(这样检查一个属性是否明智,而不去使用它吗?)
2 个回答
最好使用
if hasattr(spam,"foo"):
#dosomthing with spam.foo
else:
do_somthing()
Python文档:
hasattr(对象, 名称)
这个函数需要两个参数,一个是对象,另一个是字符串。结果如果字符串是这个对象的某个属性的名字,就返回True;如果不是,就返回False。
(这个功能是通过调用getattr(对象, 名称)来实现的,然后看看是否会抛出异常。)
更新:
如果你只是想知道属性 foo
是否存在(而不是想对这个属性做什么),那么使用 hasattr()
检查属性可能更好。
从一个 开发者/用户 的角度来看,我得承认,使用 hasattr()
更能表达你的意图。而且这样写的代码会更简洁:
if not hasattr(spam,'foo'):
do_something()
hasattr()
的文档说明它是通过以下方式实现的:
(这是通过)调用
getattr(object, name)
并查看是否抛出异常来实现的。
所以基本上 hasattr()
做的事情和你现在做的一样。在这种情况下,我会选择使用内置的解决方案,也就是 hasattr()
。这样做不会让你的代码运行得更快。
Python 鼓励使用 EAFP 的原则:
请求原谅比请求许可更容易
所以,如果你大致知道 spam
通常会有一个 foo
属性(这样代码会稍微快一点),那么这样做是完全可以的。
否则,如果 spam
大部分时间没有 foo
属性,那么这种方法会更好:
if hasattr(spam, 'foo'):
bar = spam.foo
else:
do_somthing()
我链接的维基百科部分对此有描述。引用(这里的 EAFP 版本 指的是你写的代码示例):
这两个代码示例的效果是一样的,尽管会有性能差异。当 spam 有属性 eggs 时,EAFP 示例会 运行得更快。当 spam 没有属性 eggs(即“特殊”情况)时,EAFP 示例会 运行得更慢。如果 特殊情况很少,那么 EAFP 版本 的平均性能会 优于 另一种方法。
这其实很明显,因为(使用 EAFP)你不需要每次在访问属性之前都检查对象。