如何动态地将mixin添加为基类而不出现MRO错误?

2024-09-22 20:21:14 发布

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

假设我有一个类ABC

AB都是类C的混合类。

class A( object ):
    pass
class B( object ):
    pass
class C( object, A, B ):
    pass

这在实例化类C时不起作用。我必须从类C中删除object才能使其起作用。(否则你会遇到核磁共振问题)。

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

不过,我的案子有点复杂。在我的例子中,类C是一个服务器,其中AB是在启动时加载的插件。它们位于自己的文件夹中。

我还有一个名为Cfactory的类。在Cfactory中,我有一个__new__方法,它将创建一个完全功能的对象C。在__new__方法中,我搜索插件,使用__import__加载它们,然后将它们分配给C.__bases__ += (loadedClassTypeGoesHere, )

所以下面是一个可能性:(使它相当抽象)

class A( object ):
    def __init__( self ): pass
    def printA( self ):   print "A"
class B( object ):
    def __init__( self ): pass
    def printB( self ):   print "B"
class C( object ):
    def __init__( self ):  pass
class Cfactory( object ):
    def __new__( cls ):
        C.__bases__ += ( A, )
        C.__bases__ += ( B, )
        return C()

这再次将不起作用,并将再次给出MRO错误:

TypeError: Cannot create a consistent method resolution
order (MRO) for bases object, A

一个简单的解决方法是从AB中删除object基类。但是,这将使它们成为旧样式的对象,当这些插件单独运行时,应该避免这些对象(这应该是可能的,从UnitTest的角度来看)

另一个简单的解决方法是从C中删除object,但这也会使它成为一个旧样式的类,并且C.__bases__将不可用,因此我不能向C的基部添加额外的对象

对于这个问题,什么是一个好的架构解决方案?您将如何做这样的事情?现在我可以为插件本身使用旧式类。但我宁愿不用它们。


Tags: 对象方法self插件newobjectinitdef