我有一个继承自具有自己元类Meta
的类X
。 我还想让X从SQL Alchemy的声明性基类派生。 但是我不能简单地这样做。
def class MyBase(metaclass = Meta):
#...
def class X(declarative_base(), MyBase):
#...
由于我会遇到元类冲突错误:'派生类的元类必须是其所有基类的元类的(非严格)子类'。我理解需要创建一个新的元类,该元类从Meta和声明基类使用的任何元类(我认为是DeclarativeMeta?)派生。那么,仅写下面这些代码就足够了吗:
def class NewMeta(Meta, DeclarativeMeta): pass
def class MyBase(metaclass = NewMeta):
#...
def class X(declarative_base(), MyBase):
#...
我尝试了这个方法,似乎有效;但是我担心可能会出现一些问题。
我读了手册,但对我来说有点晦涩难懂。这是什么意思?
编辑:
我的类使用的代码如下:
class IterRegistry(type):
def __new__(cls, name, bases, attr):
attr['_registry'] = {}
attr['_frozen'] = False
print(name, bases)
print(type(cls))
return type.__new__(cls, name, bases, attr)
def __iter__(cls):
return iter(cls._registry.values())
class SQLEnumMeta(IterRegistry, DeclarativeMeta): pass
class EnumType(metaclass = IterRegistry):
def __init__(self, token):
if hasattr(self, 'token'):
return
self.token = token
self.id = len(type(self)._registry)
type(self)._registry[token] = self
def __new__(cls, token):
if token in cls._registry:
return cls._registry[token]
else:
if cls._frozen:
raise TypeError('No more instances allowed')
else:
return object.__new__(cls)
@classmethod
def freeze(cls):
cls._frozen = True
def __repr__(self):
return self.token
@classmethod
def instance(cls, token):
return cls._registry[token]
class C1(Base, EnumType, metaclass = SQLEnumMeta):
__tablename__ = 'c1'
#...
return super().__new__(cls, name, bases, attr)
替换return type.__new__(cls, name, bases, attr)
。虽然不是万无一失,但至少比仅仅希望在Declarative Base中没有__new__
要好一些。当然,所有这些多重继承都非常不安全,因为没有人对行为做出精确的约定... - max