请教一个Python中super的问题?
ringa_lee
ringa_lee 2017-04-18 10:15:10
[Python讨论组]
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)
<ipython-input-9-a47164864387> in <module>()
----> 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
ringa_lee
ringa_lee

ringa_lee

全部回复(3)
大家讲道理
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)
伊谢尔伦

问题出在super函数
换成下面这种就可以了,super是调用指定类的父类的某个函数,在B中应该调用B的父类(也就是A)的__init__函数

class B(A):
    def __init_(self):
        self.b = 'b'
        super(B, self).__init__()
迷茫

建议理解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__()

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号