Python Mixin for-uuu str_u和方法解析Ord

2024-09-30 20:29:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我发现,我用Python编写的许多类都包含一小部分变量,我在调用str()时确实希望看到这些变量,而为每个类重写{}相当麻烦。因此,我做了下面的混音

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)

但是,如果我写一个类

^{pr2}$

我在实例化时得到以下错误

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

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


Tags: nameselfforreturnobjectdefattrsgenerate
3条回答

多重继承可能会令人费解。为了在使用mixin时保持简单的继承,可以在类之外定义函数,并在定义时将其分配到类中。在

class StrMixin:     # class here used only as a namespace

    @staticmethod   # not needed with Python 3
    def __str__(self):
        name = self.__class__.__name__ + ': '
        attrs = [ '{}={}'.format(k,v) for (k,v) in self.__dict__.items() ]
        return name + ', '.join(attrs)
    __repr__ = __str__

class C(object):
    __str__, __repr__ = StrMixin.__str__, StrMixin.__repr__

或者,如果将mixin函数存储在模块中,则可以在类中使用它,如下所示:

^{pr2}$

当您定义:

class StrMixin(object):
  ...

编译器知道在类的MRO中,StrMixinobject之前。在

当您这样做时:

^{pr2}$

您已经告诉编译器在MRO中,objectStrMixin之前。但是object也必须在StrMixin之后,所以它必须在MRO中出现两次,这是不允许的。在

如果你说:

class C(StrMixin, object):
    pass

那么MRO就是CStrMixinobject,它满足两个类所施加的顺序。不存在重复,因为尽管object被引用了两次,但定义之间没有冲突。在

你自己回答了这个问题-第二个object是多余的。类C有两个基:object和StrMixin。然而,StrMixin的基也是object,所以它会混淆它应该首先解析哪个对象。MRO将其计算为(C,STRMixin,object,object),其中有重复的对象。在这种特殊情况下,解决方案应该是什么似乎是显而易见的,但是增加几个类,MRO可能变得不那么清晰。E、 g

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

E的MRO是什么?不管它是什么,它真的很复杂,有重复的,可能还有几个循环。在

MRO解释得很好here,您的具体情况在页面下面三分之二处被处理,第一个例子是“Bad Method Resolution Orders”。在

相关问题 更多 >