当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《为什么`type(x).__在Python标准contextlib中输入__(x)`而不是`x.__输入__()`?》经验,为你挑选了1个好方法。

在contextlib.py,我看到ExitStack类正在呼叫__enter__()经由类型的对象方法(type(cm)),而不是直接方法调用给定对象(cm).

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

例如,

发生错误时它会提供更好的异常跟踪吗?

它只是特定于一些模块作者的编码风格?

它有任何性能优势吗?

它是否避免了复杂类型层次结构的一些工件/副作用?

Andrea Corbe.. 14

首先,当你这样做时会发生这种情况with something,这不仅仅是contextlib在类型上查找特殊方法.此外,值得注意的是,其他特殊方法也是如此:例如,a + b结果type(a).__add__(a, b).

但为什么会这样呢?这是一个经常在python-dev和python-ideas邮件列表上启动的问题.当我说"经常"时,我的意思是"经常".

最后一个是这些:缺少核心功能:+ - */| &不要调用getattr和消除特殊方法查找.

以下是一些有趣的观点:

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

(资源)

值得注意的是,这种行为比这更神奇.即使查看类,隐式特殊方法查找绕过__getattr____getattribute__元类.因此,特殊方法查找不仅仅是在类而不是实例上启动的普通查找; 它是一个完全神奇的查找,不会在任何级别上使用通常的属性访问自定义挂钩.

(资源)

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

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

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

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

当你写作时obj.attr,type(obj).__getattribute__('attr')会被召唤.__getattribute__()查找attr实例字典(即obj.__dict__)和类命名空间的默认实现,如果失败,则调用type(obj).__getattr__('attr').

现在,这是一个快速的解释,我省略了一些细节,但它应该让你知道属性查找有多复杂,以及它变得多慢.短路特殊方法查找确实提供了性能改进,因为obj.__enter__()以"经典"方式查找可能太慢.



1> Andrea Corbe..:

首先,当你这样做时会发生这种情况with something,这不仅仅是contextlib在类型上查找特殊方法.此外,值得注意的是,其他特殊方法也是如此:例如,a + b结果type(a).__add__(a, b).

但为什么会这样呢?这是一个经常在python-dev和python-ideas邮件列表上启动的问题.当我说"经常"时,我的意思是"经常".

最后一个是这些:缺少核心功能:+ - */| &不要调用getattr和消除特殊方法查找.

以下是一些有趣的观点:

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

(资源)

值得注意的是,这种行为比这更神奇.即使查看类,隐式特殊方法查找绕过__getattr____getattribute__元类.因此,特殊方法查找不仅仅是在类而不是实例上启动的普通查找; 它是一个完全神奇的查找,不会在任何级别上使用通常的属性访问自定义挂钩.

(资源)

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

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

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

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

当你写作时obj.attr,type(obj).__getattribute__('attr')会被召唤.__getattribute__()查找attr实例字典(即obj.__dict__)和类命名空间的默认实现,如果失败,则调用type(obj).__getattr__('attr').

现在,这是一个快速的解释,我省略了一些细节,但它应该让你知道属性查找有多复杂,以及它变得多慢.短路特殊方法查找确实提供了性能改进,因为obj.__enter__()以"经典"方式查找可能太慢.

推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有