Python中请问类名()何时会等于类名.__call__() ?
class Foo:
def __call__():
print("call")
if name==‘main’:
Foo()
print("--------")
Foo.call()
上面代码输出如下:
call
请问为何这里 Foo()不等于 Foo.call(),什么情况下才会相等呢? 谢谢
Python中请问类名()何时会等于类名.__call__() ?
Foo() 执行的是__init__方法 可以试试这样 f = Foo() f()
在Python里,类名() 这个写法,本质上就是在调用 类名.__call__()。更准确地说,当你写 MyClass() 来实例化一个类时,Python解释器会去查找并执行这个类(注意,是类对象本身)的 __call__ 方法。
默认情况下,一个普通类的 __call__ 方法继承自其元类(通常是 type)。type.__call__() 这个方法里封装了创建实例的标准流程:它会先调用类的 __new__ 方法来创建实例对象,然后再用这个实例和参数去调用 __init__ 方法进行初始化,最后返回这个实例。
所以,类名() 永远等于 类名.__call__() 的执行结果。它们不是“有时”相等,而是在语法层面就是等价的。类名() 是语法糖,底层就是去调用那个 __call__ 方法。
你可以通过一个简单的例子来验证这一点,并看看如果我们自定义类的 __call__ 方法(这通常不是用来控制实例化,而是让实例可调用)会发生什么:
class MyClass:
# 这是实例的初始化方法
def __init__(self, x):
self.x = x
print(f"__init__ called with x={x}")
# 这个__call__让MyClass的'实例'变得可调用,而不是类本身。
# 它并不影响 `MyClass()` 这个实例化过程。
def __call__(self, y):
print(f"Instance __call__ called with y={y}")
return self.x + y
# 1. 正常的实例化过程 `MyClass(10)`, 它触发的是元类type的__call__
obj = MyClass(10)
# 输出: __init__ called with x=10
# 2. 此时obj是一个实例,调用obj(5)才会触发上面定义的实例的__call__方法
result = obj(5)
# 输出: Instance __call__ called with y=5
print(result) # 输出: 15
# 3. 那么,类的__call__在哪?它就是type.__call__。
# 我们可以直接调用它,效果和 `MyClass(10)` 一模一样。
obj2 = MyClass.__call__(10)
# 输出: __init__ called with x=10
print(obj2.x) # 输出: 10
总结一下关键点:
类名()这个语法,翻译过来就是类名.__call__(参数)。- 这个
__call__方法是类对象(作为元类type的实例)的方法,默认由type.__call__提供。 - 你在类定义里写的
def __call__(self, ...),是赋予这个类的“实例”可调用的能力,和“类”本身如何被调用(即实例化)是两回事。
简单建议: 理解 类名() 等价于调用其元类的 __call__ 方法是掌握Python对象模型的关键一步。
class Foo:
def call(self):
print(“call”)
if name==‘main’:
f = Foo()
print("--------")
f()
谢谢,我还是有疑问,为何__call__加入 self 参数后就使得 Foo()会调用 Foo.call() ,否则这不会调用呢?

