Python多继承

摘自python cookbook:

class Base:
  def __init__(self):
    print('Base.__init__')
class A(Base):
  def __init__(self):
    Base.__init__(self)
    print('A.__init__')
class B(Base):
  def __init__(self):
    Base.__init__(self)
    print('B.__init__')
class C(A,B):
  def __init__(self):
    A.__init__(self)
    B.__init__(self)
    print('C.__init__')

如果你运行这段代码就会发现 Base.init() 被调用两次,如下所示:

>>> c = C()
Base.__init__
A.__init__
Base.__init__
B.__init__
C.__init__
>>>

用super():

class Base:
  def __init__(self):
    print('Base.__init__')
class A(Base):
  def __init__(self):
    super().__init__()
    print('A.__init__')
class B(Base):
  def __init__(self):
    super().__init__()
    print('B.__init__')
class C(A,B):
  def __init__(self):
    super().__init__() # Only one call to super() here
    print('C.__init__')

运行这个新版本后,你会发现每个 init() 方法只会被调用一次了:

>>> c = C()
Base.__init_
B.__init__
A.__init__
C.__init__
>>>

为了弄清它的原理,我们需要花点时间解释下Python是如何实现继承的。 对于你定义的
每一个类而已,Python会计算出一个所谓的方法解析顺序(MRO)列表。 这个MRO列表就
是一个简单的所有基类的线性顺序表。例如:

>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>,
<class '__main__.Base'>, <class 'object'>)
>>>

当你使用 super() 函数时,Python会在MRO列表上继续搜索下一个类。 只要每个重定义
的方法统一使用 super() 并只调用它一次, 那么控制流最终会遍历完整个MRO列表,每
个方法也只会被调用一次。 这也是为什么在第二个例子中你不会调用两次
Base.init() 的原因。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容