动态设置带有装饰器的方法
Set methods with decorators dynamically
我有这个class:
class SomeMixin:
permissions = (SomePermission,)
methods = ('GET',)
@list_route(methods=methods, url_path='en', permission_classes=permissions)
def en_list(self):
return get_translated_objects(self, 'en')
@list_route(methods=methods, url_path='ru', permission_classes=permissions)
def ru_list(self):
return get_translated_objects(self, 'ru')
@detail_route(methods=methods, url_path='en', permission_classes=permissions)
def en_detail(self):
return get_translated_object(self.get_object(), 'en')
@detail_route(methods=methods, url_path='ru', permission_classes=permissions)
def ru_detail(self):
return get_translated_object(self.get_object(), 'ru')
我以后可以有更多的语言,这不是一个好的解决方案。
我想创建语言列表循环并使用 setattr(self, func_name, func) 向 class 添加方法,例如:
langs = ('en', 'ru')
for lang in langs:
setattr(self, func.__name__, func)
但是我应该给每个方法添加装饰器,我该怎么做呢?
我相信您应该能够将此示例的内容修补到您的代码中。也就是说,从 http header 和 return 适当的响应中检测语言似乎是一种更好的方法。
这种方法虽然功能性但不是最干净的。
# This decorator is meant to simulate the decorator exposed by django
def route(url, language, method):
def wrapper(func):
def inner(*args, **kwargs):
print('url => {0}'.format(url))
print('language => {0}'.format(language))
print('method => {0}'.format(method))
func(*args, **kwargs)
return inner
return wrapper
# This class is analogous to your SomeMixin class
class foo(object):
def __init__(self):
method = 'GET'
# fields holds the parameters that will change for each method like url
# and language
fields = (('en', '/en', 'en_list'), ('ru', '/ru', 'ru_list'))
for lang, url, func_name in fields:
setattr(self, func_name, route(url=url, language=lang, method=method)(self.func_creator(lang)))
def func_creator(self, language):
def inner():
print('hello in {0}'.format(language))
return inner
def main():
foo_instance = foo()
print('Calling foo.en_list()')
foo_instance.en_list()
print()
print('Calling foo.ru_list()')
foo_instance.ru_list()
if __name__ == '__main__':
main()
我有这个class:
class SomeMixin:
permissions = (SomePermission,)
methods = ('GET',)
@list_route(methods=methods, url_path='en', permission_classes=permissions)
def en_list(self):
return get_translated_objects(self, 'en')
@list_route(methods=methods, url_path='ru', permission_classes=permissions)
def ru_list(self):
return get_translated_objects(self, 'ru')
@detail_route(methods=methods, url_path='en', permission_classes=permissions)
def en_detail(self):
return get_translated_object(self.get_object(), 'en')
@detail_route(methods=methods, url_path='ru', permission_classes=permissions)
def ru_detail(self):
return get_translated_object(self.get_object(), 'ru')
我以后可以有更多的语言,这不是一个好的解决方案。
我想创建语言列表循环并使用 setattr(self, func_name, func) 向 class 添加方法,例如:
langs = ('en', 'ru')
for lang in langs:
setattr(self, func.__name__, func)
但是我应该给每个方法添加装饰器,我该怎么做呢?
我相信您应该能够将此示例的内容修补到您的代码中。也就是说,从 http header 和 return 适当的响应中检测语言似乎是一种更好的方法。 这种方法虽然功能性但不是最干净的。
# This decorator is meant to simulate the decorator exposed by django
def route(url, language, method):
def wrapper(func):
def inner(*args, **kwargs):
print('url => {0}'.format(url))
print('language => {0}'.format(language))
print('method => {0}'.format(method))
func(*args, **kwargs)
return inner
return wrapper
# This class is analogous to your SomeMixin class
class foo(object):
def __init__(self):
method = 'GET'
# fields holds the parameters that will change for each method like url
# and language
fields = (('en', '/en', 'en_list'), ('ru', '/ru', 'ru_list'))
for lang, url, func_name in fields:
setattr(self, func_name, route(url=url, language=lang, method=method)(self.func_creator(lang)))
def func_creator(self, language):
def inner():
print('hello in {0}'.format(language))
return inner
def main():
foo_instance = foo()
print('Calling foo.en_list()')
foo_instance.en_list()
print()
print('Calling foo.ru_list()')
foo_instance.ru_list()
if __name__ == '__main__':
main()