Python装饰符*args和**kwargs

python decorators *args and ** kwargs(Python装饰符*args和**kwargs)

本文介绍了Python装饰符*args和**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,然后遍历列表和dict以找到该特定参数,但明确地说,它要简单得多,也更干净:

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

但通用的装饰符比特定的装饰符要多得多。

这篇关于Python装饰符*args和**kwargs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:Python装饰符*args和**kwargs

基础教程推荐