Python 如何堆叠元类

Python 如何堆叠元类,python,python-2.x,metaclass,Python,Python 2.x,Metaclass,我想“堆叠”元类 def dec(cls): class newmeta(cls.__metaclass__): def __call__(cls, *args, **kwargs): obj = cls.__metaclass__.__call__(cls, *args, **kwargs) obj.x *= 2 #this happens AFTER __init__ is called cls.__metacl

我想“堆叠”元类

def dec(cls):
    class newmeta(cls.__metaclass__):
        def __call__(cls, *args, **kwargs):
            obj = cls.__metaclass__.__call__(cls, *args, **kwargs)
            obj.x *= 2 #this happens AFTER __init__ is called
    cls.__metaclass__ = newmeta
    return cls

@dec
@dec
class Foo(object):
    def __init__(self, x):
        self.x = 5

print Foo().x #expect 20
但是,我似乎无法以这种方式访问
Foo.\uuuuu元类\uuuuuu
。。。。事实上
(\uuuuu元类\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu


这件事怎么办

如果您谈论的是Python3.5+,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

更改现有的
cls.\uuuu元类\uuuuu
无效,因为元类决定类的构建方式,您必须使用元类创建新的类对象:

def dec(cls):
    basetype = type(cls)
    class newmeta(basetype):
        def __call__(cls, *args, **kwargs):
            obj = super(newmeta, cls).__call__(*args, **kwargs)
            obj.x *= 2
            return obj
    new_cls = newmeta(cls.__name__, cls.__bases__, dict(cls.__dict__))
    return new_cls


@dec
@dec
class Bar(object):

    def __init__(self):
        self.x = 5


o = Bar()
print o.x
收益率:

20

ps:此方法适用于python 2和python 3。

您实际想用它实现什么?例如,您读过吗?目标是在调用
\uuuu init\uuu
方法后执行一系列事件。我可能只是用mixin解决它,并在最后调用一堆超级用户。“元类比99%的用户应该担心的更神奇。”如果有一种方法不使用它们就能实现你想要的,那就去做吧。