动态添加基类?
假设我有一个基础类,定义如下:
class Form(object):
class Meta:
model = None
method = 'POST'
现在有个开发者来了,定义了他的子类,如下:
class SubForm(Form):
class Meta:
model = 'User'
结果突然间,method
这个属性就消失了。我该怎么“找回来”,而不强迫用户让他的元类继承我的元类呢?我能不能在初始化时,或者在元类的__new__
函数中,动态地给Form.Meta
添加一个基础类?
5 个回答
1
也许你可以用这样的元类:
class _Meta:
model = None
method = "Post"
class MetaForm(type):
def __init__(cls, name, bases, dct):
super(MetaForm, cls).__init__(name, bases, dct)
if hasattr(cls, 'Meta'):
meta = getattr(cls, 'Meta')
for k,v in _Meta.__dict__.items():
check = meta.__dict__.get(k)
if not check:
meta.__dict__[k] = v
else:
setattr(cls, "Meta", _Meta)
class Form(object):
__metaclass__ = MetaForm
class SubForm(Form):
class Meta:
model = 'User'
class Sub2Form(Form):
pass
sub_form = SubForm()
sub2_form = Sub2Form()
print sub_form.Meta.method # prints "Post"
print sub2_form.Meta.model # prints None
这段代码其实很简单,你可能需要根据自己的需求稍作调整。
4
你真的需要把Meta定义成那样吗?如果你只是想通过 form.Meta.method
来访问它,那为什么不直接用一个点字典(dotdict)呢?
class dotdict(dict):
def __getattr__(self, attr):
return self.get(attr, None)
__setattr__= dict.__setitem__
__delattr__= dict.__delitem__
这样你就可以这么做:
class Form(object):
def __init__(self):
self.Meta = dotdict()
self.Meta.model = None
self.Meta.method = 'POST'
class SubForm(Form):
def __init__(self):
Form.__init__(self)
self.Meta.model = 'User'
9
只要它们不会覆盖你的 __init__
方法,或者这个方法会被调用(比如通过 super
),你就可以对 Meta
这个内部类进行修改:
class Form(object):
class Meta:
model = None
method = "POST"
def __init__(self, *args, **kwargs):
if self.__class__ != Form:
self.Meta.__bases__ += (Form.Meta,)
# other __init__ code here.
class SubForm(Form):
class Meta:
model = 'User'