In [1]: class A(object): ...: def __init__(self): ...: self.a = 'a' ...: In [2]: class B(A): ...: def __init__(self): ...: self.b = 'b' ...: In [3]: temp = B() In [4]: print(temp.a) --------------------------------------------------------------------------- AttributeError Traceback (most recent call last)in () ----> 1 print(temp.a)
因为B没有属性a所以会报错,这个问题可以通过super解决
In [5]: class B(A): ....: def __init_(self): ....: self.b = 'b' ....: super(A, self).__init__() ....: In [6]: temp = B() In [7]: print(temp.a) a
我想问的就是下面这中情况,super的调用在self = 'b'之后
,为什么print(temp.a)的值会是b而不是a
?如果是C++中的构造函数好像会将B类中a的值覆盖,各位网友能否解释一下。
In [8]: class B(A): ....: def __init__(self): ....: self.a = 'b' ....: super(A, self).__init__() ....: In [9]: temp = B() In [10]: print(temp.a) b
建议理解super(cls, self)的实现,就能解释你的现象。
用直白的话描述,super(cls, self)返回的是self.__class__.mro()中cls的下一个类。
1、你调用super(A, self)时,self.__class__.mro()为[<class '__main__.B'>, <class '__main__.A'>, <type 'object'>]
2、类A在self__class__.mro()中的下一个类,其实是object
3、综上,super(A, self)其实是在调用object.__init__(),根本没调用过A的__init__(),故self.a不会如愿被覆盖
class A(object): def __init__(self): self.a = 'a' class B(A): def __init__(self): self.a = 'b' print 'mro =', self.__class__.mro() super(A, self).__init__() temp = B() print(temp.a)
输出:
mro = [<class '__main__.B'>, <class '__main__.A'>, <type 'object'>] b
那么,改为super(B, self)即可,因为此时,实际调用A.__init__()
问题出在super
函数
换成下面这种就可以了,super是调用指定类的父类的某个函数,在B中应该调用B的父类(也就是A)的__init__函数
class B(A): def __init_(self): self.b = 'b' super(B, self).__init__()
class A(object): def __init__(self): self.a = 'a' class B(A): def __init__(self): self.a = "b" super(B, self).__init__() tmp = B() print(tmp.a)
输出a
应该是super用错了
其实可以写成这样:
class A(object): def __init__(self): self.a = 'a' class B(A): def __init__(self): self.a = "b" super().__init__() tmp = B() print(tmp.a)