您能告诉我部分函数在这里如何工作吗?
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
答案 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!