为什么在Python标准contextlib中使用type(x).__ enter __(x)而不是x .__ enter __()`?

为什么在Python标准contextlib中使用type(x).__ enter __(x)而不是x .__ enter __()`?,第1张

为什么在Python标准contextlib中使用type(x).__ enter __(x)而不是x .__ enter __()`?

首先,这就是您执行 *** 作时发生的事情

withsomething
,而不仅仅是
contextlib
在类型上查找特殊方法。另外,值得注意的是,其他特殊方法也会发生同样的情况:例如,
a +b
结果为
type(a).__add__(a, b)

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

最后一个是:缺少核心功能:+- / | &不要调用

getattr*
和Eliminate特殊方法查找。

以下是一些有趣的观点:

当前的行为是设计使然-特殊方法被视为对象类上的插槽,而不是实例属性。这允许解释器绕过正常实例属性查找过程中的几个步骤。

(资源)

值得注意的是,这种行为比这更神奇。即使在类,隐特殊方法查找旁路抬头

__getattr__
__getattribute__
元类的。因此,特殊的方法查找不仅仅是发生在类而不是实例上的普通查找。这是一个完全魔术的查找,不会在任何级别使用常规的attribute-
access-customization挂钩。

(资源)

此行为也记录在参考文档中:特殊方法查找,其中说:

__getattribute__()
以这种方式绕过机器为解释器内的速度优化提供了很大的空间,但以牺牲一些特殊方法的灵活性为代价(特殊方法必须在类对象本身上设置,以便由解释器一致地调用)

简而言之, 性能是主要关注的问题 。但是,让我们仔细看看。

type(obj).__enter__()
和之间有什么区别
obj.__enter__()

当您编写时

obj.attr
type(obj).__getattribute__('attr')
将被调用。Looks的默认实现会在实例字典(即)和类名称空间中进行
__getattribute__()
查找,否则将调用。
attr``obj.__dict__``type(obj).__getattr__('attr')

现在,这是一个快速的解释,我已经省略了一些细节,但是,它应该使您了解属性查找的复杂程度以及其查找速度。短路特殊方法查找肯定会改善性能,因为

obj.__enter__()
以“经典”方式查找可能太慢。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5663020.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存