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

标签 python metaclass callable

我想了解 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/

相关文章:

python - 解决错误: local variable 'counter' referenced before assignment

python - 数据科学家如何组织代码结构以提供最小且可重用的数据管道示例?

Python:查找列表元素之间的差异

python - Django 重复模型定义/字段

php - 如何在类范围之外的可调用上下文中访问 $this?

python - 如何使用 Kupfer (python) 修复 TypeError : glib. spawn_async?

python - import 是否调用 __new__ 静态方法?

Python3 元类 : use to validate constructor argument

java - “管道未连接”到 Java Callable 子节点

java - 我们可以从 Java 中的 Future 对象中获取 Callable 对象吗?