本人在学习Python
的过程中发现了这么一个问题, 自己查阅了一点资料但是还是没有理解, 如下:
版本为python3.6
代码如下:
class X:
def __init__(self):
self.x = 10
def f(self):
return self.x
class Y(X):
def __init__(self):
self.x = 100
def b(self):
return super().f()
x = X()
y = Y()
print(y.b()) # -> 100, 为什么不是 10?
问题描述:
本人对于super()
其实一直不是特别理解, 网上查了一下资料以后理解为super()
会返回MRO
列表里面的下一个类, 那么我把Y
的MRO
打印出来:
print('mro', Y.mro()) # mro [<class '__main__.Y'>, <class '__main__.X'>, <class 'object'>]
那么根据MRO
列表, 下面的类就是X
了, 那么super().f()
实际就为X.f()
, 那么里面的return self.x
应该就是X
实例, 可是实际运行结果显示self
是子类Y
的实例. 既然这里的super().f()
调用了父类的方法, 里面的self
不应该是指代父类实例么? 这是我难以理解的地方.
表述有点乱, 望有前辈能给予解答, 不胜感激!
问题补充:
写这个问题的时候又想到了一点:
继承的时候常常会有super().__init__()
来调用父类的__init__()
函数, 调用这个函数的时候里面的self
其实也就指代了子类实例? 好像与之前的问题一个意思, 但是不知道怎么理解, 望能有前辈指点一下.
说一下
self
究竟是什么.类方法的第一个参数
self
是实例本身,也就是A=X()
这个A.这个还是很清楚的,我们确定了这个之后,再转头去看你举的例子.
我们都知道,子类的方法会覆盖父类的同名方法.
先看下边的例子:
我们看到,在子类没有覆盖父类的方法时,子类的方法是等于父类的方法的,很纯粹的等于,内存中地址都是一样的.
所以你那个例子中
super().f()
就和直接f()
没区别的.同样,在子类的实例里也不会莫名其妙冒出来一个父类的实例作为
self
参数传给f()
方法,而且,你子类的init方法覆盖了父类的init方法,所以父类的init方法根本就没有执行.从那个角度来说,都是万万不会等于父类初始化的值的.