用于__str__和方法解析顺序的Python Mixin

duc*_*thd 6 python mixins

我发现我用Python编写的许多类都包含一小部分变量,我实际上希望在调用时看到这些变量str(),并且__str__(self)每次重写都很麻烦.因此,我煮了下面的mixin,

class StrMixin(object):
  '''
  Automatically generate __str__ and __repr__
  '''
  def __str__(self):
    import types
    name = self.__class__.__name__ + ': '
    attrs = [ '{}={}'.format(k,v) for (k,v) in self.__dict__.items() ]
    return name + ', '.join(attrs)

  def __repr__(self):
    return str(self)
Run Code Online (Sandbox Code Playgroud)

但是,如果我写一堂课,

class C(object, StrMixin):
    pass
Run Code Online (Sandbox Code Playgroud)

我在实例化时收到以下错误,

TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases object, StrMixin
Run Code Online (Sandbox Code Playgroud)

当然,包括object这里是多余的,但这里到底发生了什么?

Dun*_*can 11

当你定义:

class StrMixin(object):
  ...
Run Code Online (Sandbox Code Playgroud)

编译器知道,StrMixin来之前object在类的MRO.

当你这样做时:

class C(object, StrMixin):
    pass
Run Code Online (Sandbox Code Playgroud)

你告诉MRO object之前的编译器StrMixin.但object也必须在之后来,StrMixin所以它必须在MRO中出现两次,这是不允许的.

如果你说:

class C(StrMixin, object):
    pass
Run Code Online (Sandbox Code Playgroud)

那么MRO根本C,StrMixin,object其满足了由这两个类规定的顺序.没有重复,因为尽管object引用了两次,但定义之间没有冲突.


aqu*_*tae 1

您自己回答了这个问题 - 第二个object是多余的。C 类有两个基础:object 和 StrMixin。然而,StrMixin 的基础也是对象,因此它对于应该首先解析哪个对象感到困惑。MRO 将其计算为 (C, STRMixin, object, object),其中有重复的对象。在这种特殊情况下,解决方案应该是什么似乎是显而易见的,但添加更多的类,MRO 可能会变得不太清晰。例如

class A(object):
    pass
class B(object, A):
    pass
class C(object, A):
    pass
class D(object, B, C):
    pass
class E(object, A, D):
    pass
Run Code Online (Sandbox Code Playgroud)

E 的 MRO 是什么?不管它是什么,它确实很复杂,有重复,可能还有一些循环。

MRO在这里解释得很好,并且您的具体情况在页面的三分之二处进行了处理,即“错误方法解决订单”下的第一个示例。