gpt4 book ai didi

python - 为什么 `type(x).__enter__(x)` 而不是 Python 标准上下文库中的 `x.__enter__()`?

转载 作者:太空狗 更新时间:2023-10-29 20:13:45 25 4
gpt4 key购买 nike

contextlib.py ,我看到 ExitStack 类正在通过类型对象 (type(cm)) 调用 __enter__() 方法,而不是直接调用给定对象 (cm) )。

我想知道为什么或为什么不。

例如,

  • 它是否在发生错误时提供更好的异常跟踪?
  • 是否仅特定于某些模块作者的编码风格?
  • 它有任何性能优势吗?
  • 它是否避免了一些具有复杂类型层次结构的工件/副作用?

最佳答案

首先,当您使用某些东西 时会发生这种情况,不仅仅是contextlib 会在类型上查找特殊方法。此外,值得注意的是,其他特殊方法也会发生同样的情况:例如a + b 结果为 type(a).__add__(a, b)

但为什么会这样呢?这是一个经常在 python-dev 和 python-ideas 邮件列表中引发的问题。当我说“经常”时,我的意思是“非常经常”。

最后一个是这些:Missing Core Feature: + - * / | & do not call getattrEliminating special method lookup .

这里有一些有趣的点:

The current behaviour is by design - special methods are looked up as slots on the object's class, not as instance attributes. This allows the interpreter to bypass several steps in the normal instance attribute lookup process.

(Source)

It is worth noting that the behavior is even more magical than this. Even when looked up on the class, implicit special method lookup bypasses __getattr__ and __getattribute__ of the metaclass. So the special method lookup is not just an ordinary lookup that happens to start on the class instead of the instance; it is a fully magic lookup that does not engage the usual attribute-access-customization hooks at any level.

(Source)

此行为也记录在引用文档中:Special method lookup ,它说:

Bypassing the __getattribute__() machinery in this fashion provides significant scope for speed optimisations within the interpreter, at the cost of some flexibility in the handling of special methods (the special method must be set on the class object itself in order to be consistently invoked by the interpreter).

简而言之,性能是主要关注点。但让我们仔细看看这个。

type(obj).__enter__()obj.__enter__() 有什么区别?

当您编写 obj.attr 时,将调用 type(obj).__getattribute__('attr')__getattribute__() 的默认实现在实例字典(即 obj.__dict__)和类命名空间中查找 attr,如果失败, 调用 type(obj).__getattr__('attr')

现在,这是一个快速的解释,我省略了一些细节,但是它应该让您了解属性查找可以有多复杂,它可以变得多慢。短路特殊方法查找肯定会提供性能改进,因为以“经典”方式查找​​ obj.__enter__() 可能太慢了。

关于python - 为什么 `type(x).__enter__(x)` 而不是 Python 标准上下文库中的 `x.__enter__()`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34490998/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com