python - 使用装饰器提供新的 args、kwargs
问题描述
我做过一些关于装饰器的研究,主要是关于典型的用例。事实证明,在大多数情况下,它们充当验证器、计时器、权限检查器——非常透明的东西。我想知道使用它们来预先计算并为装饰函数提供一些变量是否是 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)
这是对的吗?我应该改变什么?
解决方案
我不会在这里使用装饰器;我会编写一个函数来返回特定数据的闭包。
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')
(我没有测试,但我很确定如果你如图所示装饰闭包,或者只是返回一个未装饰的函数并 writefn1 = 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'
它具有相同的行为,但对意图不太清楚。装饰器中隐藏了太多东西。
推荐阅读
- swift - 如何使元组类型快速符合协议?
- machine-learning - 如何确定 RetinaNet 模型的锚大小?
- r - 从 R 中的数据图中查找百分比
- java - 使用 while 循环创建用户界面
- view - 当 map 函数在 couchbase 视图中为某个文档运行时,是否可以通过 id 获取另一个文档中包含的数据?
- python-2.7 - 提供了密钥和iv,加密后我得到不同的值,然后是预期的
- python-3.x - 如何在 Python 中告诉客户端服务器中不存在文件
- php - 如何查看特定网页上的上次访问日期?我想在该页面上显示 7 天后过期的链接
- html - 如何从 MySQL 数据库填充 ejs 表单下拉列表选项?
- javascript - 试图让 d3 刻度每 X 个月出现一次,格式正确