来自元类工厂的多重继承
我希望 SuperClass12
继承自 SuperClass1
和 SuperClass2
:
def getClass1():
class MyMetaClass1(type):
def __new__(cls, name, bases, dct):
print dct.get("Attr","")+"Meta1"
return super(MyMetaClass1, cls).__new__(cls, name, bases, dct)
return MyMetaClass1
def getClass2():
class MyMetaClass2(type):
def __new__(cls, name, bases, dct):
print dct.get("Attr","")+"Meta2"
return super(MyMetaClass2, cls).__new__(cls, name, bases, dct)
return MyMetaClass2
class SuperClass1():
__metaclass__ = getClass1()
def fun1(self):
pass
class SuperClass2():
__metaclass__ = getClass2()
def fun2(self):
pass
class MyClass1(SuperClass1):
Attr = "MC1"
class MyClass2(SuperClass2):
Attr = "MC2"
def getClass12():
class myMultiMeta(getClass1(),getClass2()):
pass
return myMultiMeta
class SuperClass12(SuperClass1,SuperClass2):
#class SuperClass12(): gives no errors in class construction but then
#fun1() and fun2() are not members of SuperClass12.
__metaclass__ = getClass12()
class MyClass12(SuperClass12):
Attr = "MC12"
Instance = MyClass12()
Instance.fun1()
Instance.fun2()
遗憾的是我遇到了这个错误:
TypeError:调用元类基元类冲突时出错:派生类的元类必须是其所有基类的元类的(非严格)子类
但我无法理解为什么,因为元类 myMultiMeta
我的派生类 SuperClass12
确实是其所有基类的元类 (MyMetaClass1,MyMetaClass2)
的子类(SuperClass1,SUperClass2)
。
I want SuperClass12
to inherit from SuperClass1
and SuperClass2
:
def getClass1():
class MyMetaClass1(type):
def __new__(cls, name, bases, dct):
print dct.get("Attr","")+"Meta1"
return super(MyMetaClass1, cls).__new__(cls, name, bases, dct)
return MyMetaClass1
def getClass2():
class MyMetaClass2(type):
def __new__(cls, name, bases, dct):
print dct.get("Attr","")+"Meta2"
return super(MyMetaClass2, cls).__new__(cls, name, bases, dct)
return MyMetaClass2
class SuperClass1():
__metaclass__ = getClass1()
def fun1(self):
pass
class SuperClass2():
__metaclass__ = getClass2()
def fun2(self):
pass
class MyClass1(SuperClass1):
Attr = "MC1"
class MyClass2(SuperClass2):
Attr = "MC2"
def getClass12():
class myMultiMeta(getClass1(),getClass2()):
pass
return myMultiMeta
class SuperClass12(SuperClass1,SuperClass2):
#class SuperClass12(): gives no errors in class construction but then
#fun1() and fun2() are not members of SuperClass12.
__metaclass__ = getClass12()
class MyClass12(SuperClass12):
Attr = "MC12"
Instance = MyClass12()
Instance.fun1()
Instance.fun2()
sadly I've got this error:
TypeError: Error when calling the metaclass bases metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
but I cannot understand why, since the metaclass myMultiMeta
of my derived class SuperClass12
indeed is a subclass of bothe the metaclasses (MyMetaClass1,MyMetaClass2)
of all its bases (SuperClass1,SUperClass2)
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正如 Michael Merickel 所指出的,
getClass()
函数需要在每次调用时返回相同的对象,继承才能正常工作。仅仅相同的类是不够好的。这里有一种方法可以做到这一点,即滥用一个类,使其表现得像您的getClass()
函数。由于类定义仅执行一次,因此返回时MyMetaClass1
始终是相同的对象。您也可以这样做,使用真实函数并滥用可变默认参数来缓存类实例:
您会注意到这里反复出现的主题:滥用 Python 功能。 :-) 这通常表明您正在做的事情也许可以通过其他方式做得更好。例如,为什么要使用工厂,而不是仅以正常方式定义类?我已经看到类工厂有一些用处,但我认为我从未在野外见过元类工厂。
As noted by Michael Merickel, the
getClass()
functions need to return the same object on each call for your inheritance to work. A class that is merely identical isn't good enough. Here's one way to do that, abusing a class to make it act like yourgetClass()
functions. Since the class definition is only executed once,MyMetaClass1
is always the same object when returned.You could also do it like so, using a real function and abusing a mutable default argument to cache the class instance:
You will notice a recurring theme here: abuse of Python features. :-) That is usually a sign that you are doing something that maybe is done better some other way. For example, why are you using factories, rather than just defining the class the normal way? I've seen class factories have some use, but I don't think I've ever seen a metaclass factory in the wild.
请记住,
getClass1
和getClass2
返回元类的新实例。因此,当您设置 __metaclass__ = getClass1() 时,这是一个与myMultiMeta
继承的元类不同的元类。Remember that
getClass1
andgetClass2
return a new instance of the metaclass. Thus when you set__metaclass__ = getClass1()
, that is a different metaclass than the one inherited bymyMultiMeta
.这是你想要的吗?
跑步:
Is this what you want?
Run:
我感谢谁通过给出一些答案来帮助我:
这是一个不错的解决方案!
I thank who, by giving some answers, helped me:
is a not so bad solution!