在Python中,这是一种好习惯吗?

3 投票
2 回答
1064 浏览
提问于 2025-04-15 20:17
try:
    spam.foo
except AttributeError:
    do_somthing()

(这样检查一个属性是否明智,而不去使用它吗?)

2 个回答

2

最好使用

if hasattr(spam,"foo"):
   #dosomthing with spam.foo
else:
   do_somthing()

Python文档:

hasattr(对象, 名称)
这个函数需要两个参数,一个是对象,另一个是字符串。结果如果字符串是这个对象的某个属性的名字,就返回True;如果不是,就返回False。
(这个功能是通过调用getattr(对象, 名称)来实现的,然后看看是否会抛出异常。)

14

更新

如果你只是想知道属性 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)你不需要每次在访问属性之前都检查对象。

撰写回答