2017-05-14 98 views
1

我找到了一個多重繼承的例子,但不明白它的行爲方式。Python中的MRO無法正常工作

class Printable: 
    """A mixin class for creating a __str__ method that prints 
    a sequence object. Assumes that the type difines __getitem__.""" 

    def lef_bracket(self): 
     return type(self).__name__ + "[" 

    def right_bracket(self): 
     return "]" 

    def __str__(self): 
     result = self.lef_bracket() 
     for i in range(len(self)-1): 
      result += str(self[i]) + ", " 
     if len(self) > 0: 
      result += str(self[-1]) 
     return result + self.right_bracket() 

此腳本存儲在printable.py因此該類Printable以這種方式使用:

>>> from printable import * 
>>> class MySeq(list, Printable): 
...  pass 
... 
>>> my_seq = MySeq([1,2,3]) 
>>> print(my_seq) 
MySeq[1, 2, 3] 

我的問題是,爲什麼__str__方法是從Printable類,而不是繼承在list類,而MySeq方法解析順序是:

>>> MySeq.__mro__ 
(<class '__main__.MySeq'>, <class 'list'>, <class 'printable.Printable'>, <class 'object'>) 

Printable的文檔字符串中,我注意到了單詞「mixin」。爲什麼在這種情況下,我們稱之爲混合類?

回答

2
list

沒有定義__str__方法:

>>> '__str__' in list.__dict__ 
False 

因爲它沒有定義這樣的方法,在MRO下一類獲取供給它。對於一個普通的list對象,即會是object.__str__

>>> list.__mro__ 
(<class 'list'>, <class 'object'>) 
>>> list.__str__ is object.__dict__['__str__'] 
True 

但由於Printable混入,則列出之前object

>>> MySeq.__mro__ 
(<class '__main__.MySeq'>, <class 'list'>, <class '__main__.Printable'>, <class 'object'>) 
>>> MySeq.__str__ is Printable.__dict__['__str__'] 
True 

甲混合類是設計一類被添加到類層次結構中以與其他基類一起工作。 Printable是一個混合,因爲它需要別的東西實現__getitem__