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 - 不过,从那里找出所有内容可能需要一些时间和试验。
我想了解 '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__
方法做了什么。
类 本身也是第一个 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 - 不过,从那里找出所有内容可能需要一些时间和试验。