装饰器添加关键字参数

时间:2017-07-26 09:42:24

标签: python python-3.x function decorator

我试图定义一个装饰器,只是在装饰函数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参数成为name中的captured()参数。我该怎么做呢?

2 个答案:

答案 0 :(得分:1)

您可以name一个keyword-only argument来实现这一目标。目前的问题是它是一个位置参数,当你正在进行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'

答案 1 :(得分:0)

只需传递名称,即调用函数f inner = f(name,* args,** kwargs)