代码之家  ›  专栏  ›  技术社区  ›  max

用SQL Alchemy声明基处理元类冲突

  •  4
  • max  · 技术社区  · 14 年前

    我有一个 class X 它派生自一个有自己元类的类 Meta . 我还想从SQL Alchemy中的声明性基派生X。但我不能做简单的事

    def class MyBase(metaclass = Meta):
        #...
    
    def class X(declarative_base(), MyBase):
        #...
    

    因为我会得到元类冲突错误:“派生类的元类必须是其所有基元类的(非严格)子类。”。我知道我需要创建一个新的元类,它将从元和声明性基使用的任何元类派生(我认为是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'
        #...
    
    1 回复  |  直到 14 年前
        1
  •  3
  •   unutbu    14 年前

    编辑:现在已经看了 IterRegistry DeclarativeMeta

    电子注册 定义 __new__ __iter__ 陈述性媒体 定义 __init__ __setattr__ . 既然没有重叠,就不需要直接打电话 super . 尽管如此,这样做还是很好的,以验证您的代码的未来性。


    你能控制这个词的定义吗 Meta ? 你能告诉我们它的定义吗?我不认为我们可以说它有效或无效,除非我们看到的定义 .

    不呼叫 super(Meta,cls).__init__(classname, bases, dict_)

    如果你运行这个代码

    class DeclarativeMeta(type):
        def __init__(cls, classname, bases, dict_):
            print('DeclarativeMeta')
            # if '_decl_class_registry' in cls.__dict__:
            #     return type.__init__(cls, classname, bases, dict_)       
            # _as_declarative(cls, classname, dict_)
            return type.__init__(cls, classname, bases, dict_)
    
    class Meta(type):
        def __init__(cls, classname, bases, dict_):
            print('Meta')
            return type.__init__(cls, classname, bases, dict_)
    
    class NewMeta(Meta,DeclarativeMeta): pass
    
    class MyBase(object):
        __metaclass__ = NewMeta
        pass
    

    'Meta' 打印出来。 换句话说,只有 Meta.__init__ 跑起来。 DeclarativeMeta.__init__ 被跳过。

    class Meta(type):
        def __init__(cls, classname, bases, dict_):
            print('Meta')
            return super(Meta,cls).__init__(classname, bases, dict_)
    

    元初始化__ 声明性数据。\u初始化__