我已经完成了一些关于装饰器的研究,主要是关于典型的用例。事实证明,在大多数情况下,它们充当验证器,计时器,权限检查器-相当透明的东西。我想知道使用它们进行预计算并向装饰函数提供一些变量是否为pythonic。
我想到的情况如下:
装饰器:
def foo(fn):
@functools.wraps(fn)
def wrapper(*args, **kwargs):
fn_name = fn.__name__
var = Test._do_something(Test.store_dict[fn_name])
kw_args = {**kwargs, **dict(var=var)}
return fn(*args, **kw_args)
return wrapper
班级:
class Test:
store_dict = dict(fn1='fn1_operator',
fn2='fn2_operator')
@staticmethod
@foo
def fn1(dummy_data, **kwargs):
return Test.__handle_data(dummy_data=dummy_data,
**kwargs)
@staticmethod
@foo
def fn2(dummy_data, **kwargs):
return Test.__handle_data(dummy_data=dummy_data,
**kwargs)
@staticmethod
def _do_something(var):
return var
@staticmethod
def __handle_data(dummy_data, var):
return (dummy_data, var)
用法:
test_instance = Test()
test_instance.fn1(dummy_data='test')
如您所见,fn1
和fn2
方法的作用几乎相同(调用__handle_data
方法),但var
却不同。变量var
取决于所调用的函数名。调用fn1
的结果是var=fn1_operator
,依此类推。我想到Python的禅宗:
简单胜于复杂。
我怀疑它是pythonic。
另一方面,如果没有该装饰器,我的代码将有很多重复:
@staticmethod
def fn1(dummy_data):
var = _do_something('fn1')
return Test.__handle_data(dummy_data=dummy_data,
var=var)
@staticmethod
def fn2(dummy_data):
var = _do_something('fn2')
return Test.__handle_data(dummy_data=dummy_data,
var=var)
对吗?我应该改变什么?
答案 0 :(得分:2)
我不会在这里使用装饰器;我会编写一个返回特定数据闭包的函数。
def make_test(arg):
@staticmethod
def _(dummy_data):
var = _do_something(arg)
return Test.__handle_data(dummy_data, var=var)
return _
fn1 = make_test('fn1')
fn2 = make_test('fn2')
(我没有进行测试,但是我很确定,如果您如图所示装饰闭包,或者只是返回未装饰的函数并编写fn1 = staticmethod(make_test('fn1'))
等,它的工作原理都是一样的。)
使用装饰器专注于常见的外观,它看起来像
def foo(f):
def _(dummy_data):
var = _do_something(f())
return Test.__handle_data(dummy_data, var=var)
return _
@foo
def fn1(self):
return 'fn1'
@foo
def fn2(self):
return 'fn2'
具有相同的行为,但意图不明确。装饰器中隐藏了太多东西。