装饰类方法以建立方法注册表

2024-09-27 21:28:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我想要达到的目标:

我想修饰类方法定义,这样类就可以构建某些方法的注册表。其目的如下:

class NForm(FormFiller):
    @fills('name')
    def get_name(self):
        return 'gets name'

class NAForm(NForm):
    @fills('address')
    def get_address(self):
        return 'gets address'

class NBForm(NForm):
    @fills('birthday')
    def get_birthday(self):
        return 'gets birthday'

na = NAForm().filled_form() == {'address': 'gets address',
                                'name': 'gets name'}

nb = NBForm().filled_form() == {'birthday': 'gets birthday',
                                'name': 'gets name'}

我尝试的

看起来很简单,所以我为父类编写了这段代码。你知道吗

class FormFiller(object):
    _fills = {}

    @classmethod
    def fills(cls, field_name):
        def wrapper(func):
            cls._fills[field_name] = func.__name__
            return func
        return wrapper

    def filled_form(self):
        return {field_name: getattr(self, func)() for field_name, func in self._fills.items()}

并用例如@NAForm.fills('address')替换上面的修饰符。然而,这当然是不可能的,因为NAForm还没有在它自己的定义中定义。我只能写入任何一个父母的_fills属性。你知道吗

感觉想要的用例应该是可能的,但我目前不知道如何实现这一点。如果我想手动实现上述行为,我可以为每个继承添加一个中间类,例如

class FormFiller(object):
    _fills = {}
    @classmethod
    def fills(cls, field_name):
        print 'in', cls, 'adding', field_name
        def wrapper(func):
            # make a copy since _fills is like a mutable default
            cls._fills = dict(cls._fills)
            # update
            cls._fills[field_name] = func.__name__
            return func
        return wrapper

    def filled_form(self):
        return {field_name: getattr(self, func)() for field_name, func in self._fills.items()}


class NFormBase(FormFiller):
    pass

class NForm(NFormBase):
    @NFormBase.fills('name')
    def get_name(self):
        return 'gets name'

class NAFormBase(NForm):
    pass

class NAForm(NAFormBase):
    @NAFormBase.fills('address')
    def get_address(self):
        return 'gets address'

class NBFormBase(NForm):
    pass

class NBForm(NBFormBase):
    @NBFormBase.fills('birthday')
    def get_age(self):
        return 'gets birthday'


print FormFiller().filled_form()  # == {}
print NForm().filled_form()  # == {'name': 'gets name'}
print NAForm().filled_form()  # == {'name': 'gets name', 'address': 'gets address'}
print NBForm().filled_form()  # == {'birthday': 'gets birthday', 'name': 'gets name'}

这似乎是可行的,但是a)需要为每个继承步骤添加一个中间类,b)复制\u填充字典的频率要比需要的频率高很多(在每个装饰上,而不是在每个类创建时一次)。你知道吗

有没有更好的办法?如果你能给我指点方向,我会很感激的。元类是我要找的吗?你知道吗

谢谢!你知道吗


Tags: nameselfformfieldreturnaddressdefclass
1条回答
网友
1楼 · 发布于 2024-09-27 21:28:07

原来元类是我所需要的,我以前从未使用过它们,我只是在SO上找到了合适的问题:Auto-register class methods using decorator

registry = {}

class RegisteringType(type):
    def __init__(cls, name, bases, attrs):
        registry[name] = {}

        for base in bases:
            registry[name].update(**registry.get(base.__name__, {}))

        for key, val in attrs.iteritems():
            properties = getattr(val, 'register', None)
            if properties is not None:
                registry[name][key] = properties

def register(*args):
    def decorator(f):
        f.register = tuple(args)
        return f
    return decorator

class FormFiller(object):
    __metaclass__ = RegisteringType

    def filled_form(self):
        print type(self).__name__
        return registry[type(self).__name__]

class NForm(FormFiller):
    @register('name')
    def get_name(self):
        return 'gets name'

class NAForm(NForm):
    @register('address')
    def get_address(self):
        return 'gets address'

class NBForm(NForm):
    @register('birthday')
    def get_age(self):
        return 'gets birthday'

相关问题 更多 >

    热门问题