Python - Class 可调用是什么意思?

Python - What does it mean for a Class to be callable?

我想了解 'callables' 在 Python 中的含义,以及 class 可调用的含义。我正在玩以下代码:

class A(object):

    def __init__(self):
        pass

print("Is A callable? " + str(callable(A)))
a=A()
print("created a")
a()

结果如下:

Is A callable? True
created a
Traceback (most recent call last):    
File "test2.py", line 11, in <module>
a()
TypeError: 'A' object is not callable  

此外,

print(type(A.__call__()))

给出:

<class '__main__.A'>

这是否意味着 class A 有一个 __call__ 方法?为什么它是 class 类型?

每次我用 A() 实例化时是否调用 A.__call__()

当一个对象的__something__方法被调用时,会发生这样的事情:

  • 对象的class有吗?如果是,return.
  • 它的class的superclass有吗?如果是,return.
  • 它的class的superclass的superclass有吗?如果是,return.
  • ...

请注意,它从不查看对象的 class 的 class。

因为 classes 是 type 的实例(或者它的子class,见 here),classes 是可调用的(type__call__)。然而,除非 class 也定义了 __call__,它的实例不会有它,因为它永远不会在 class 的 class.

中查找

因此,从 Python 中的事实开始,通常函数是可调用的,而 classes 是可调用的。 撇开将函数标记为可调用的机制不谈,Python classes 具有如您所知的特殊方法。使 class 的 实例 可调用的方法是 __call__。因此,如果您的 class 有一个明确的 __call__ 方法,它的实例是可调用的并且故事结束:当您调用该实例时,它是被调用的 __call__ 方法。

这回答了你一半的问题 - 现在让我们检查 class 的 class 上的 __call__ 方法做了什么。

Python 中的

类 本身也是第一个 class 对象 - 但它们必须是 实例 类型。也就是说,调用 type 就像调用 class 来创建一个实例一样,会创建一个新的 class。当在代码中遇到 class 正文块时,Python 运行 时间会自动执行此操作。 (但也可以通过以其三个以上参数形式显式调用类型,以编程方式创建新的 classes)

因为 type 本身是 object 的子class - 它的 __new__ 方法是它的特殊之处,因为它创建了一个新的 class,按照 cPython ABI 的要求填充所有需要的数据结构,分配内存,并将值放入纯 Python 代码无法访问的字段中。因为它是 Python 中任何类型的 class-object 的 class,所以它被称为 metaclas。可以从类型派生其他 classes 并创建自定义元 classes,到 运行 代码,r 插入属性,注册数据等等 classes 是创建 - 但这是可选的。任何创建的 class 都会经过类型的 __new__.

当你实例化一个class?我在上面写道,使对象在 Python 中可调用的原因是在其 class 中存在 __call__ 方法。 type 是所有 class 中的 class,它 确实 具有 __call__ 方法 - 它包含编排所需的代码调用 class' __new____init__ 方法。这就是为什么 classes 是可调用的,以及为什么 Python 可以对函数调用和对象实例化使用相同的语法。

is A.__call__() being called each time I instantiate with A()?

不妥-所谓的type(A).__call__A.__call__type(A).__call__ 如果在 A 中没有定义明确的 __call__ 方法,则相同(然后搜索其 class, type __call__。但是 Python 不会通过普通属性检索隐式调用特殊方法:它们总是从对象的 class 中选取 - 而且是在 运行 时间内生成的。

您可能对 metaclass' 调用对 class 不可用感到困惑:这根本没有像 Python 的方法检索算法中那样定义。当您请求对象的属性或方法时 - 包括像 __call__ 这样的特殊方法,会在 class 中搜索描述符形式的属性(以提供自定义属性访问) - 然后class 的基础 classes,但不是 class 的 class。 (此外,对于特殊方法,它们只有在对象的 class 本身中定义时才是特殊的:直接附加到实例没有任何效果)。

发布这一切的关键文档是 Python 的 Data Model - 不过,从那里找出所有内容可能需要一些时间和试验。