动态添加基类?

时间:2010-07-02 22:38:00

标签: python inheritance syntax python-2.6

假设我的基类定义如下:

class Form(object):
    class Meta:
        model = None
        method = 'POST'

现在开发人员很长并且定义了他的子类,如:

class SubForm(Form):
    class Meta:
        model = 'User'

现在突然method属性丢失了。如何在不强迫用户继承我的meta类的情况下“恢复”?我可以在初始化程序中或在元类的Form.Meta函数中动态地将基类添加到__new__吗?

5 个答案:

答案 0 :(得分: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'

答案 1 :(得分: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'

答案 2 :(得分:1)

您可以在父对象的__init__方法中检查方法属性,并在需要时进行更新。当然,只有当您保护代码的程序员将在其构造函数中调用它时,这才有效。

class Form(object):
    def __init__(self):
            if not getattr(self.Meta,'method',False):
                    self.Meta.method='POST'
    class Meta:
       model = None
       method = 'POST'

class SubForm(Form):
    class Meta:
       model = 'User'

答案 3 :(得分: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 :(得分:0)

也许我可以省略Meta内的默认Form类,而是使用默认的dict?

meta_defaults = {'model':None, 'method':'POST'}
meta_vars = meta_defaults
meta_vars.update(Form.Meta.__dict__)