可选参数修饰符

时间:2020-04-17 20:11:42

标签: python

您能告诉我部分函数在这里如何工作吗?

def debug(func=None, *, prefix=''):
    if func is None:
        return partial(debug, prefix=prefix)
    msg = prefix + func.__name__
    @wraps(func)
    def wrapper(*args, **kwargs):
        print(msg)
        return func(*args, **kwargs)
    return wrapper

1 个答案:

答案 0 :(得分:1)

设计debug函数的目的是,当您将其用作装饰器时,可以选择使用prefix仅关键字参数来调用它:

@debug(prefix="foo"):  # calling debug with a prefix works
def foo():
    pass

@debug                 # skipping the call also works
def bar():
    pass

使用functools.partial可以做到这一点。 partial函数返回一个可调用参数,其行为与您传递的函数相同,但是只要部分对象被调用,它就会添加传递给partial的额外参数。

这是一个例子:

from functools import partial

def foo(arg1, arg2):
    print(arg1, arg2)

foo("hi", "there") # prints "hi there"

bar = partial(foo, "bar")
bar("quux") # prints "bar quux"

baz = partial(foo, arg2="baz")
baz("hmm") # prints "hmm baz"

使用@decorator的装饰器语法将在下一行定义的函数作为单个参数传递给装饰器。但是,如果您在装饰器行上调用,则该函数将传递给该调用的返回值。所以:

@debug
def foo():
    pass

等效于:

def foo():
    pass

foo = debug(foo)

位置:

@debug(prefix="foo")
def foo():
    pass

等效于:

deco = debug(prefix="foo") # this is partial(debug, prefix="foo")

@deco
def foo():
    pass

感谢partial等同于:

def foo():
    pass

foo = debug(foo, prefix="foo")  # passing both arguments here, that's not normally possible!