python3 多继承的super init问题

python中,如果存在多继承,例如

class Song(object):
    """docstring for Song"""
    def __init__(self, author):
        super(Song, self).__init__(author)
        self._author = author
class Singer(object):
    """docstring for Singer"""
    def __init__(self, name):
        super(Singer, self).__init__(name)
        self._name = name
class Mtv(Song, Singer):
    """docstring for RockSong"""
    def __init__(self, name, author):
        super(RockSong, self).__init__(name)

Mtv继承song与singer,在init方法里,如何是的两个父类进行初始化,并且完成属性赋值?

阅读 8.6k
2 个回答

使用 super() 的辦法:

class Song(object):
    def __init__(self, author):
        self._author = author

class Singer(object):
    def __init__(self, name):
        self._name = name

class Mtv(Song, Singer):
    def __init__(self, name, author):
        super().__init__(author) # init Song
        super(Song, self).__init__(name) # init Singer

mtv = Mtv('name', 'author')
print('mtv._author =', mtv._author)
print('mtv._name =', mtv._name)
# Mtv 的 MRO
(<class '__main__.Mtv'>, <class '__main__.Song'>, <class '__main__.Singer'>, <class 'object'>)`
  • SongSinger 不必呼叫 super

  • super(type, obj_or_type) 會按照 MRO 的順序去委託 type父類兄弟類 的方法來調用

    • super().__init__(author) 會找到 <class '__main__.Song'> 並調用其 __init__(author)

    • super(Song, self).__init__(name) 會找到 <class '__main__.Singer'> 並調用其 __init__(name)

結果:

mtv._author = author
mtv._name = name

P.S. 如果你是使用 Python3, 那一般的 class 不必繼承 object


這篇講的很棒, 完全理解 super: 理解 Python super

直接補上文章中的精華:

  • super 及他的兩個參數在做甚麼:

def super(cls, inst):
    mro = inst.__class__.mro()
    return mro[mro.index(cls) + 1]
  • MRO 的順序

在 MRO 中,基类永远出现在派生类后面,如果有多个基类,基类的相对顺序保持不变。


我回答過的問題: Python-QA

跟你继承的顺序有关,会先调第一个父类Song的构造,假设Song也继承了某个类X,那么再会调X的构造。完事之后再回来调Singer的构造。类似深度优先的原则

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题