2017-05-14 12 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」という単語があります。この場合、なぜそれをmixinクラスと呼びますか?

答えて

2

list__str__メソッド定義されていない:それはそのような方法を定義していないので

>>> '__str__' in list.__dict__ 
False 

を、MROの次のクラスは、それを供給するために取得します。

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

が、Printableが混入されているのでobject前に、それは、上場されています:平野listオブジェクトの場合、それはobject.__str__だろうミックスインクラスが設計されたクラスです

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

他の基本クラスと連携するためにクラス階層に追加することができます。 Printableは、何か他のものが__getitem__を実装する必要があるため、混在しています。

関連する問題