Python - What does it mean for a Class to be callable?
我试图理解Python中的"可调用文件"是什么,以及类可调用的含义。我在玩以下代码:
1 2 3 4 5 6 7 8 9
| class A(object):
def __init__(self):
pass
print("Is A callable?" + str(callable(A)))
a=A()
print("created a")
a() |
结果如下:
1 2 3 4 5 6
| 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 |
此外,
1
| print(type(A.__call__())) |
给予:
这是否意味着类A有一个__call__方法?为什么是类型类?
每次用()实例化时是否调用EDOCX1[1]?
- 你希望a()做什么?前者是可调用的,因为它在调用时委托给构造函数。但是,您还没有指定允许类实例可调用的行为,这就是后者失败的原因。
- A是可调用的,但A对象(在您的示例中,A对象)不是可调用的。
- 在Python中,一切都是一个对象。如果对象有一个__call__方法,那么它就是callaballe。方法也是对象,所以__call__本身就有一个__call__方法。
- 所以像print这样的函数有一个调用方法,等等。print.__call__.__call__.__call__.__call__。通常情况下,你不关心它在幕后如何工作,只需要使用呼叫接线员():print('hello world')。但是在自定义类的情况下,有些情况下您希望声明一个__call__方法。
- 我认为标记为重复的问题不能直接回答这个问题。(从那里的答案中可以看出这种理解是困惑的)。
- 使用__call__的类的一些实际示例:stackoverflow.com/questions/5824881/&hellip;
- 为什么你认为做a()和做a()有关系?
- 一切都是一个对象=>类是一个对象。如果对象具有调用方法,则它是可调用的。那么,为什么没有可调用调用调用方法的类?
- 有趣:docs.python.org/3/library/functions.html可调用
- "为什么类没有可调用的调用方法"-每个类都是隐式可调用的,否则无法实例化它。
- 那么,使类可调用的是它的新方法吗?因为默认情况下它没有调用方法
- 调用类时,使用其元类的__call__方法。默认值为type.__call__,它将调用类的构造函数方法__new__和__init__。
所以,从一个事实开始,在Python中,通常函数是可调用的,类是可调用的。除了将函数标记为可调用的机制之外,如您所知,Python类还有一些特殊的方法。使类实例可调用的方法是__call__。因此,如果您的类有一个显式的__call__方法,那么它的实例是可调用的,并且是故事的结尾:当您调用该实例时,调用的是__call__方法。
这回答了你一半的问题——现在让我们检查一下类上的__call__方法做了什么。
Python中的类本身也是第一类对象——但它们必须是类型的实例。也就是说,当调用一个类来创建一个实例时,调用type,创建一个新的class。当在代码中遇到类体块时,python运行时会自动执行此操作。(但也可以通过在其三+参数形式中显式调用类型,以编程方式创建新类)
由于type本身是object的一个子类,它的__new__方法是它所具有的特殊特性,因为它创建了一个新类,按照cpython abi的要求填充所有需要的数据结构,分配内存,并将值放入纯python代码无法访问的字段中。因为它是Python中任何类对象的类,所以称为元clas。可以从类型派生其他类并创建自定义元类,以运行代码、R插入属性、注册数据等,但这是可选的。创建的任何类都通过类型的__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__在A中没有明确定义的__call__方法(然后在其类type中搜索__call__时是相同的。但是,Python不会通过普通的属性检索隐式地调用特殊的方法:它们总是从对象的类中挑选出来的——这是在运行时内部创建的。
您可能会对元类的调用不可用于类感到困惑:这与Python的方法检索算法中的定义不同。当您请求一个对象的属性或方法(包括像__call__这样的特殊方法)时,将以描述符(提供自定义属性访问)的形式搜索该类的属性,然后搜索该类的基类,但不搜索该类的类。(另外,对于特殊方法,只有在对象的类本身中定义它们时,它们才是特殊的:直接附加到实例没有效果)。
所有这些都发布的关键文档是Python的数据模型——不过,可能需要一些时间和实验来解决所有问题。
当调用对象的__something__方法时,会发生如下情况:
- 对象的类是否具有它?如果是,返回。
- 它的类的超类有吗?如果是,返回。
- 它的类的超类的超类有吗?如果是,返回。
- …
请注意,它从不查看对象的类的类。
由于类是type的实例(或它的子类,请参阅此处),因此类是可调用的(type有__call__。但是,除非类也定义了__call__,否则它的实例将没有它,因为它永远不会在类的类中查找。