gpt4 book ai didi

python - type(1) 是否等同于 type.__call__(1)?

转载 作者:太空宇宙 更新时间:2023-11-03 12:26:19 26 4
gpt4 key购买 nike

我在Jupyter控制台运行代码(Python的版本是2.7.14),

type(1)
Out[71]: int

type.__call__(1)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-72-0ed097e2c413> in <module>()
----> 1 type.__call__(1)

TypeError: descriptor '__call__' requires a 'type' object but received a 'int'

我猜 type(...) 等同于 type.__call__(...) 但它似乎不是。所以我想知道:

  1. 当我调用 type(1)type(name, base, dict) 时,python 解释器做了什么?
  2. 什么时候调用 type.__call__(...)

谢谢。

最佳答案

简短版本:type.__call__ 可以解析为两个合理的东西:表示用于调用 type 本身的方法的绑定(bind)方法,或表示用于调用 type 实例的方法。您期待第一个结果,但实际得到的是第二个。


长版:

some_callable(thing) 通常等同于 some_callable.__call__(thing)。例如,print(1) 等同于 print.__call__(1)(只要您打开了 from __future__ import print_function) :

>>> print(1)
1
>>> print.__call__(1)
1

type 是可调用的,type(thing) 等同于 type.__call__(thing),除了属性查找会遇到复杂情况。

type.__call__ 属性查找期间,Python 在 type 及其父类(super class)(只是 object)中搜索 __dict__'__call__' 条目。 Python 搜索type 的类型和type 的类型的父类(super class)以查找这样的__dict__ 条目。 (您可以在 type_getattro 中看到负责调用这些搜索的代码,这是处理类型属性查找的 C 函数。)因为 type 是它自己的类型,所以这两个搜索都找到 type .__dict__['__call__'].

其中一个搜索优先。做出选择的方式,以及选择甚至重要的原因,是 descriptor protocol .如果第一次搜索成功,则描述符协议(protocol)将正常应用以查找类属性 (descriptor.__get__(None, cls));如果第二次搜索获胜,描述符协议(protocol)将正常应用以查找实例属性 (descriptor.__get__(instance, cls))。第二次搜索需要赢得 type.__call__(thing) 才能表现得像 type(thing),但只有 type.__dict__['__call__ '] 是一个数据描述符,但现在不是。

第一次搜索获胜。描述符协议(protocol)通常用于查找类属性,查找 type.__call__ 的结果是 unbound 方法。它表示 type 实例的通用 __call__ 方法,而不是 type__call__ 实例方法-as-类型实例。它需要被称为

type.__call__(type, 1)

等同于type(1)


毕竟,您可能想知道 type(thing) 如何在不遇到所有这些复杂情况的情况下工作。在语言语义上,Python 只在查找 type__call__ 方法调用它时才进行第二次搜索,所以第一次搜索无法取胜,因为它没有甚至不会发生。在实际实现方面,CPython 实际上根本不查找 __call__ 方法;它查找type 的类型,转到__call__ 对应的type 类型的C 级插槽,并调用the function it finds。 .对于在 Python 中实现的 __call__ 方法,C 槽将包含一个查找和调用 Python 方法的函数,但对于在 C 中实现的 __call__,C 槽包含__call__ 直接实现。

关于python - type(1) 是否等同于 type.__call__(1)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52397650/

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