Python 3.X中显式调用__call__为何生效且触发__init__?
问题解答
为什么Python 3.X中代码可行,Python 2.X中不行?
Python 3和Python 2在类的实现上存在核心差异:
- Python 3中所有类默认都是新式类,自动继承自
object,而所有新式类都是元类type的实例。元类type自带__call__方法,当Test类没有自定义__call__时,会从元类继承这个方法,因此Test.__call__()能正常调用。 - Python 2中,若类没有显式继承
object,则属于经典类,这类类不属于元类type的实例,也没有继承__call__方法,所以调用Test.__call__()会因找不到方法而报错。如果在Python 2中将Test改为新式类(class Test(object):),也能触发和Python 3相同的行为。
为什么调用__call__却执行了__init__?
你调用的Test.__call__()本质是元类type的__call__方法,它的执行逻辑就是类实例化的完整流程:
- 调用
Test.__new__(Test)创建Test类的实例 - 实例创建成功后,自动调用
Test.__init__(实例)完成初始化 - 返回初始化后的实例
这和直接写Test()的执行逻辑完全一致——因为Test()本身就是Python解释器自动调用type.__call__(Test)的语法糖。所以你看到的"constructor called"其实是__init__方法被触发的结果。
补充验证
可以通过打印Test.__call__的来源直观看到差异:
# Python 3中执行 print(Test.__call__) # 输出:<method-wrapper '__call__' of type object at 0x...> # 说明是元类type的方法 # Python 2中经典类执行 print(Test.__call__) # 报错:AttributeError: class Test has no attribute '__call__'
内容的提问来源于stack exchange,提问作者user19946454
相关产品推荐
相关产品推荐

