我想要实现的目标:
我想装饰类方法定义,以便该类可以构建某些方法的注册表。其目的如下:
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('地址')
。然而,这当然是不可能的,因为 NAForm 尚未在其自己的定义中定义。我只能写入任何 parent 的 _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)比必要的更频繁地复制_fills字典(在每个装饰上而不是每个类创建一次)。
有更好的方法吗?如果有任何正确方向的指示,我将不胜感激。元类是我正在寻找的吗?
谢谢!
最佳答案
事实证明元类正是我所需要的,我以前从未使用过它们,我只是在 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'
关于python - 装饰类方法以构建方法注册表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48709145/