我希望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)
的子类。
答案 0 :(得分:3)
正如Michael Merickel所指出的,getClass()
函数需要在每次调用时返回相同的对象才能继承。一个仅仅相同的类是不够好的。这是一种方法,滥用一个类使其像你的getClass()
函数。由于类定义只执行一次,因此MyMetaClass1
在返回时始终是同一个对象。
class getClass1(object):
class MyMetaClass1(type):
def __new__(cls, name, bases, dct):
print dct.get("Attr","")+"Meta1"
return super(MyMetaClass1, cls).__new__(cls, name, bases, dct)
class __metaclass__(type):
def __call__(cls):
return cls.MyMetaClass1
您也可以这样做,使用真实函数并滥用可变默认参数来缓存类实例:
def getClass1(cls=[]):
if not cls:
class MyMetaClass1(type):
def __new__(cls, name, bases, dct):
print dct.get("Attr","")+"Meta1"
return super(MyMetaClass1, cls).__new__(cls, name, bases, dct)
cls.append(MyMetaClass1)
return cls[0]
你会注意到一个反复出现的主题:滥用Python功能。 :-)这通常表明你正在做一些可能在其他方面做得更好的事情。例如,您为什么使用工厂,而不仅仅是以正常的方式定义类?我见过班级工厂有一些用途,但我不认为我曾经见过野外的元类工厂。
答案 1 :(得分:2)
请记住,getClass1
和getClass2
会返回元类的新实例。因此,当您设置__metaclass__ = getClass1()
时,这是与myMultiMeta
继承的元类不同的元类。
答案 2 :(得分:1)
这是你想要的吗?
class MyMetaClass1(type):
def __new__(cls, name, bases, dct):
print dct.get("Attr","")+"Meta1"
return super(MyMetaClass1, cls).__new__(cls, name, bases, dct)
class MyMetaClass2(type):
def __new__(cls, name, bases, dct):
print dct.get("Attr","")+"Meta2"
return super(MyMetaClass2, cls).__new__(cls, name, bases, dct)
class SuperClass1():
__metaclass__ = MyMetaClass1
def fun1(self):
pass
class SuperClass2():
__metaclass__ = MyMetaClass2
def fun2(self):
pass
class MyClass1(SuperClass1):
Attr = "MC1"
class MyClass2(SuperClass2):
Attr = "MC2"
class MyMultiMeta(MyMetaClass1, MyMetaClass2):
pass
class SuperClass12(SuperClass1, SuperClass2):
#class SuperClass12(): gives no errors in class construction but then
#fun1() and fun2() are not members of SuperClass12.
__metaclass__ = MyMultiMeta
class MyClass12(SuperClass12):
Attr = "MC12"
Instance = MyClass12()
Instance.fun1()
Instance.fun2()
执行命令
vic@ubuntu:~/Desktop$ python test.py
Meta1
Meta2
MC1Meta1
MC2Meta2
Meta1
Meta2
MC12Meta1
MC12Meta2
vic@ubuntu:~/Desktop$
答案 3 :(得分:0)
我感谢谁,通过给出一些答案,帮助了我:
def getClass12():
class myMultiMeta(SuperClass1.__metaclass__,SuperClass2.__metaclass__):
pass
return myMultiMeta
class SuperClass12(SuperClass1,SuperClass2):
__metaclass__ = getClass12()
是一个不太糟糕的解决方案!