Python hasattr() 是有害的

发布于 2025-01-06 13:38:24 字数 2808 浏览 13 评论 0

不要使用 Python 的 hasattr() ,除非你想要它奇奇怪怪,或者你正编写纯 Python 3 代码。这是 Python 最常见的讨论之一,因此,不是不断的为每一个提供依据,而是一劳永逸:

不要:

if hasattr(x, "y"):
    print(x.y)
else:
    print("no y!")

而是要这样做:

try:
    print(x.y)
except AttributeError:
    print("no y!")

或者:

y = getattr(x, "y", None)
if y is not None:
    print(y)
else:
    print("no y!")

特别是在你处理不属于自己的类时。hasattr() 并不比 getattr() 快,因为它经历完全相同的查找过程,然后丢掉结果。

为什么?

它看起来似乎差不多,而额外的行令人感到厌烦,但是在 Python 2 上使用接近于这样写:

try:
    print(x.y)
except:
    print("no y!")

这几乎不会是你想要的,因为它隐藏了属性(property) 中的错误!

例如:

>>> class C(object):
...     @property
...     def y(self):
...         0/0
...
>>> hasattr(C(), "y")
False

由于在第三方类中,你不能知道一个属性是不是一个属性(property)(或者在数月或数年后更新为一个属性),因此这是危险的。你觉得这没啥大不了,是吗?看看这个闪闪发光的 例子 !另一个明显的影响是在属性上使用 hasattr() 并不执行它们的 getter 函数,这使得名字具有误导性。

对于它的价值,Python 3 使其恢复正常:

>>> class C:
...     @property
...     def y(self):
...         0/0
...
>>> hasattr(C(), "y")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in y
ZeroDivisionError: division by zero

这使得当同时为 Python 2 和 Python 3 编写混合代码时,它成为了一种边缘情况。但是,你会预期 hasattr() 抛出该错误吗?


细心的读者可能会问, AttributeErrors 呢?事实上,没有办法区分一个 AttributeError 是由于属性缺失引起的,还是由一个错误的属性引起的。The outlined approaches reduce your possible errors to only that one and avoid confusing differences in behavior between Python 2 and 3.

当然,对于自己的代码,依然可以使用 hasattr() 。但你必须跟踪它,并在你的类发生改变时记得解决它。这一切都增加了不必要的精神负担,而目的只在于节省一些打字。

附注:是滴,标题很烂。因为我已经写了这篇文章,所以可以在讨论的时候向人们展示它。我没想到它会在 Hacker News 上排行第一,并且我同意“被认为是有害的”这种说法正在过时。只是,我并没有花费太多时间来担心,而是在起床和去上班之间进行处理;它只是突然出现在我的脑海里的第一件事。感谢您的理解。未来可能会修改它,反正这个主题是中立的。

再附注:有些人对于我敢匹配 Python 3 中一个很好用的函数感到很愤怒。因为没人应该写 Python 2 了。虽然我并不是一个讨厌 Python 3 的 Armin,但必须承认,现今大多数的 Python 代码不是 Python 2 就是混合的。而对于一些人提及的许多混合库,我发现 Python 2 和 3 之间的行为差异甚至比 Python 2 自身的行为还要糟糕,而这会使人措手不及。所以,冷静下来,喝杯可可,然后移植一些一些库。

补充说明

  1. getattr() 例子假设属性的确实等价于其值为 None (这是常见的)。如果你想要区别那两种情况,使用一个警戒值。
  2. 至少在 CPython 中。

原文: hasattr() Considered Harmful

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

梦萦几度

暂无简介

文章
评论
27 人气
更多

推荐作者

夢野间

文章 0 评论 0

百度③文鱼

文章 0 评论 0

小草泠泠

文章 0 评论 0

zhuwenyan

文章 0 评论 0

weirdo

文章 0 评论 0

坚持沉默

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文