Python 3中派生类默认构造函数实例化父类的底层机制探究
Python 3中派生类默认构造函数实例化父类的底层机制探究
嘿,我来一步步给你拆解这段代码背后的逻辑,还有你关心的那些底层细节~
首先先把你的代码贴出来,方便对照:
class A(): def __init__(self, x): self.x = x def __str__(self): return self.x class B(A): def __str__(self): return super().__str__() b = B("Hi") print(b)
运行这段代码确实会输出Hi,下面咱们逐个问题拆解:
一、派生类没写__init__时,默认构造是怎么调用父类构造的?
在Python里,如果你定义了一个子类但没有显式写出__init__方法,当你实例化这个子类的时候,Python会自动按照「方法解析顺序(MRO)」去查找第一个包含__init__方法的父类,然后调用那个父类的__init__。
放到你的代码里,类B继承自A,B自己没写__init__,所以Python会找到父类A的__init__方法,然后调用它来完成实例的初始化。
这里要注意:调用父类__init__的时候,传递的self参数其实是子类B的实例对象,不是父类A的实例——Python在实例化时会先创建子类的实例,再把它绑定到构造方法的self参数上,不管这个构造方法是父类还是子类的。
二、传给子类实例的参数是怎么映射到父类构造参数的?
当你执行b = B("Hi")时,你传入的"Hi"这个参数,会被直接传递给刚才找到的父类构造方法(也就是A的__init__)。
具体来说:
- Python先创建一个B类的空实例;
- 因为B没有
__init__,所以调用A的__init__(self, x); - 把刚才创建的B实例自动绑定到
self参数,把"Hi"绑定到x参数; - 执行
self.x = x,其实就是给B类的实例b添加了一个x属性,值为"Hi"。
三、最后输出Hi的调用链是怎样的?
这部分就和__str__方法有关了:
- 你调用
print(b)的时候,Python会自动调用实例b的__str__方法来获取要打印的字符串; - B类重写了
__str__,里面用super().__str__()调用了父类A的__str__方法; - A的
__str__返回self.x,而这里的self还是B的实例b,它的x属性是"Hi",所以最终返回"Hi",print就输出了这个结果。
备注:内容来源于stack exchange,提问作者Aroonalok
相关产品推荐
相关产品推荐

