4. 带有不定长参数的函数的装饰器

知识点回顾

函数形参的定义方式:

函数传参的方式:

lst = [1, 2, 3]
print(*lst)  # 等同于 print(1,2,3)
func(**{'a':1, 'b':2})
# 等同于 func(a=1, b=2)

以上是《python编程语言基础篇》的内容,这里不再赘述。

带有不定长参数的函数的装饰器

当被装饰函数有不定长参数和返回值时,则装饰器返回的函数的参数通常使用 *args**kwargs 来接收所有的传参。

在调用被装饰函数时,也使用 *args**kwargs 来拆解 args 元组和 kwargs 字典进行位置传参和关键字传参。

def mydeco(fn):
    '''定义一个 包裹被装饰函数的装饰器,此装饰器在调用函数之前或之后都打印函数名!'''
    def wrap(*args, **kwargs):
        print(f'调用:{fn.__name__} 之前')
        r = fn(*args, **kwargs)
        print(f'调用:{fn.__name__} 之后')
        return r
    return wrap

@mydeco
def myadd(a, b, c=0, d=0):
    return a + b + c + d

@mydeco
def mypower_mod(a, b, *, mod=0):
    if mod:
        return a ** b % mod
    return a ** b

print(myadd(1, 2, 3))  # 6
print(mypower_mod(5, 2))  # 25 # 计算 5的平方
print(mypower_mod(4, 3, mod=5))  #4 # 计算 4的立方再对5求余数

上述装饰器 mydeco 可以装饰任何的函数,并能够完美调用被装饰函数,且能在调用被装饰函数之前执行相应的自定义代码。