Python 可选参数修饰符

Python 可选参数修饰符,python,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

你能给我解释一下分部函数是如何工作的吗

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

debug
函数的设计目的是,当您将其作为装饰程序应用时,如果需要,可以选择使用
prefix
关键字only参数调用该函数:

@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对象时,它将添加您传递给
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
的decorator语法将下一行定义的函数作为单个参数传递给decorator。但是,如果您在decorator行上调用某个函数,那么函数将被传递给调用的返回值。因此:

@debug
def foo():
    pass
相当于:

def foo():
    pass

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

@deco
def foo():
    pass
def foo():
    pass

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

@debug(prefix="foo")
def foo():
    pass
相当于:

def foo():
    pass

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

@deco
def foo():
    pass
def foo():
    pass

foo = debug(foo, prefix="foo")  # passing both arguments here, that's not normally possible!
由于
部分
,这相当于:

def foo():
    pass

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

@deco
def foo():
    pass
def foo():
    pass

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

这回答了你的问题吗?不完全是这样,我理解部分是如何工作的。但是我不知道在部分返回之后我们是如何访问函数体的。