我想了解 Python 中的“可调用项”是什么,以及类可调用项的含义。我正在玩以下代码:
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'>
这是否意味着类 A 有一个 __call__
方法?为什么它是类型类?
A.__call__()
是否在我每次用 A() 实例化时被调用?
最佳答案
因此,首先要了解在 Python 中,通常函数是可调用的,而类也是可调用的。
撇开将函数标记为可调用的机制不谈,如您所知,Python 类具有特殊方法。使类的实例可调用的方法是__call__
.所以,如果你的类(class)有明确的 __call__
方法,它的实例是可调用的并且故事结束:当你调用实例时,它是 __call__
调用的方法。
这回答了你一半的问题 - 现在让我们检查一下 __call__
是什么类的类上的方法。
Python 中的类本身也是一流对象 - 但它们必须是 type
的实例 .即调用type
当一个人调用一个类来创建一个实例时,创建一个新的 class
.当在代码中遇到类主体 block 时,Python 运行时会自动执行此操作。
(但也可以通过以其三个以上参数形式显式调用 type
以编程方式创建新类)
作为type
本身是 object
的子类- 它的 __new__
方法是它的特殊之处,因为它创建了一个新类,按照 cPython ABI 的要求填充所有需要的数据结构,分配内存,并将值放入纯 Python 代码无法访问的字段中。因为它是 Python 中任何类型的类对象的类,所以它被称为元类。可以从 type
派生其他类并创建自定义元类,在创建类时运行代码、插入属性、注册数据等等——但这是可选的。创建的任何类都经过 type
的 __new__
.
当你实例化一个类时?我在上面写道,使对象在 Python 中可调用的是 __call__
的存在。类中的方法。 type
作为所有类中的类,它确实具有__call__
方法 - 它包含编排调用类“__new__
”所需的代码和 __init__
方法。这就是为什么类是可调用的,以及为什么 Python 可以对函数调用和对象实例化使用相同语法的原因。
is
A.__call__()
being called each time I instantiate with A()?
不正确-所谓的是type(A).__call__
. A.__call__
和 type(A).__call__
如果没有显式 __call__
将是相同的A
中定义的方法(然后搜索其类 type
以查找 __call__
。但是 Python 不会通过普通属性检索隐式调用特殊方法:它们总是从对象的类中选取 - 并且是在运行时内生成的。
您可能对元类的调用对类不可用感到困惑:这根本不是像 Python 的方法检索算法中那样定义的。当您请求对象的属性或方法时 - 包括像 __call__
这样的特殊方法,该类以描述符的形式搜索属性(以提供自定义属性访问) - 然后是该类的基类,但不是该类的类。 (此外,对于特殊方法,它们只有在对象的类本身中定义时才是特殊的:直接附加到实例没有任何效果)。
发布这一切的关键文档是 Python 的 Data Model - 不过,可能需要一些时间和实验才能从那里找出所有内容。
关于Python - 类可调用是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48461989/