【问题标题】:MRO in Python doesn't work as expectedPython 中的 MRO 无法按预期工作
【发布时间】:2017-05-14 12:02:42
【问题描述】:

我找到了一个多重继承的例子,但不明白它的行为方式。

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 类?

【问题讨论】:

    标签: python multiple-inheritance method-resolution-order


    【解决方案1】:

    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__

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-22
      相关资源
      最近更新 更多