Python多继承

2017-05-25  本文已影响0人  开罗酒吧

摘自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() 的原因。

上一篇下一篇

猜你喜欢

热点阅读