请教一个Python中super的问题?

 席昀2010_445_882 发布于 2022-10-25 18:38
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
3 个回答
  • 建议理解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__()

    2022-10-27 00:31 回答
  • 问题出在super函数
    换成下面这种就可以了,super是调用指定类的父类的某个函数,在B中应该调用B的父类(也就是A)的__init__函数

    class B(A):
        def __init_(self):
            self.b = 'b'
            super(B, self).__init__()
    2022-10-27 00:31 回答
  • 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)
    2022-10-27 00:32 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有