如何堆叠元类
How to stack metaclasses
我想要"stack"元类。
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.__metaclass__
....实际上 ("__metaclass__" in Foo.__dict__) == False
人们会怎么做呢?
如果您谈论的是 Python 3.5+,则不再支持 __metaclass__
,如此处所述
Alter existing cls.__metaclass__
无效,因为 metaclass 决定了 class 的构建方式,您必须使用您的 meta[=21] 创建一个新的 class 对象=]:
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 和 3。
我想要"stack"元类。
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.__metaclass__
....实际上 ("__metaclass__" in Foo.__dict__) == False
人们会怎么做呢?
如果您谈论的是 Python 3.5+,则不再支持 __metaclass__
,如此处所述
Alter existing cls.__metaclass__
无效,因为 metaclass 决定了 class 的构建方式,您必须使用您的 meta[=21] 创建一个新的 class 对象=]:
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 和 3。