所以,这是一个由两部分组成的问题 -
- 在使用装饰器时,Python中是否有惯用的方式将参数注入函数签名中?
例如:
def _mydecorator(func):
def wrapped(someval, *args, **kwargs):
do_something(someval)
return func(*args, **kwargs)
return wrapped
@_mydecorator
def foo(thisval, thatval=None):
do_stuff()
这其中的原因在于使用SaltStack的运行模块时,您可以在模块中定义函数,并且可以通过“salt-run”命令调用这些函数。如果上述示例是一个名为“bar”的Salt运行模块,那么我可以运行:
salt-run bar.foo aval bval
盐源运行通过导入模块并使用您在命令行上给出的参数调用函数。以_开头或位于类中的模块中的任何函数都将被忽略,并且无法通过盐源运行运行。
因此,我希望定义类似于超时修饰符的东西来控制函数运行的时间。
我意识到我可以做类似以下的事情:
@timeout(30)
def foo():
...
但我希望将该值设置为可配置的,这样我就可以运行类似以下的代码:
salt-run bar.foo 30 aval bval
salt-run bar.foo 60 aval bval
上述装饰器可以使用,但感觉有些不自然,因为它改变了函数的签名,除非用户查看装饰器,否则他们无法了解。
我还有另外一种情况,我想要创建一个装饰器,在 Salt 运行程序执行之前处理“prechecks”(预检查)。但是,这个 precheck 需要从被装饰的函数中获取一些信息。以下是一个示例:
def _precheck(func):
def wrapper(*args, **kwargs):
ok = False
if len(args) > 0:
ok = run_prechecks(args[0])
else:
ok = run_prechecks(kwargs['record_id'])
if ok:
func(*args, **kwargs)
return wrapper
@_precheck
def foo(record_id, this_val):
do_stuff()
这种方式似乎有些笨拙,因为它要求被装饰的函数a)有一个名为“record_id”的参数,并且b)它是第一个参数。
现在,因为我正在编写所有这些函数,所以这不算什么大问题,但似乎还有更好的方法来解决这个问题(比如不使用装饰器来尝试解决这个问题)。