添加关键字参数的修饰器



我正在尝试定义一个装饰器,该装饰器仅向装饰函数f添加一个关键字参数。f可能具有(位置、关键字等(参数的任意组合。我试过这个:

def capture_wrap(f):
def captured(name=False, *args, **kwargs):
"""name can be False, True or str. if str, then use it as a name."""
print (name, f, args, kwargs)
inner = f(*args, **kwargs)
if name is False:
return inner
elif name is True:
return capture(inner)
else:
return capture(inner, name=name)
return captured

如果我尝试将其与接受单个参数的函数一起使用:

@capture_wrap
def any_of(s):
"""s must be in the right format.
See https://docs.python.org/3/library/re.html#regular-expression-syntax ."""
return wrap('[', Dinant(s, escape=False), ']')
0-9A-Fa-f <function any_of at 0x7fb370548a60> () {}
Traceback (most recent call last):
File "./dinant.py", line 222, in <module>
hex = one_or_more(any_of('0-9A-Fa-f'))
File "./dinant.py", line 116, in captured
inner = f(*args, **kwargs)
TypeError: any_of() missing 1 required positional argument: 's'

我收到一个错误,因为 any 参数成为captured()中的name参数。我应该如何正确执行此操作?

你可以name一个仅关键字的参数来实现这一点。目前的问题是它是一个位置参数,当你做any_of('foo')时,'foo'被传递给name参数。

def capture_wrap(f):
def captured(*args, name=False, **kwargs):
"""name can be False, True or str. if str, then use it as a name."""
print(name, f, args, kwargs)
inner = f(*args, **kwargs)
return inner
return captured

@capture_wrap
def any_of(s1, s2, s3, **kwargs):
return "I do something"

演示:

>>> any_of('0-9A-Fa-f', 1, 2)
False <function any_of at 0x1041daea0> ('0-9A-Fa-f', 1, 2) {}
'I do something'
>>> any_of('0-9A-Fa-f', 2, 3, a=1, b=2, name='some-name')
some-name <function any_of at 0x1041daea0> ('0-9A-Fa-f', 2, 3) {'a': 1, 'b': 2}
'I do something'

只需在调用函数 f 的位置传递名称 inner = f(name, *args, **kwargs(

最新更新