繁体   English   中英

python装饰器* args和** kwargs

[英]python decorators *args and ** kwargs

我是编码的新手,我一直在努力吸收尽可能多的东西。 我不了解你们发布的很多技术说明,因此请尽量使用简单的英语。 我了解装饰器功能的工作原理,但是我的问题是遵循代码逻辑-特别是为什么我们必须添加* args和** kwargs。 声明我们传入装饰器函数的任何传入具有参数的函数是否总是将相同的参数传递给包装函数是正确的,因为它嵌套在装饰器中? 那就是我在这里想念的。 我不明白原始函数的参数是如何传递的。

让我们举一个简单的例子:

def tracing(func):
    @functools.wraps
    def wrapper(*args, **kwargs):
        logging.debug(f'Calling {func.__name__}')
        try:
            return func(*args, **kwargs)
        finally:
            logging.debug(f'Called {func.__name__}')
    return wrapper

@tracing
def spam():
    print('spam')

@tracing
def add3(n):
    return n+3

没错,我们需要使用*args, **kwargs是为了使我们可以将相同的*args, **kwargs传递给包装函数。

这称为“转发”或“完美转发”。 这个想法是, tracing不必知道有关其包装的函数的任何信息,它可以接受任何位置和关键字参数集,并返回任何内容,并且包装器仍然有效。


对于某些装饰器,这是不合适的。 例如,一个装饰器旨在使用一个特定的参数作为缓存键来缓存所有具有相同API的一组函数, 可以使用*args, **kwargs ,然后仔细检查列表和字典以查找该特定参数,但是要明确得多:

def caching_spam(func):
    cache = {}
    @functool.wraps
    def wrapper(eggs, beans, spam, cheese):
        if spam not in cache:
            cache[spam] = func(eggs, beans, spam, cheese)
        return cache[spam]
    return wrapper

但是,通用装饰器要比特定装饰器多得多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM