4. 带有不定长参数的函数的装饰器
知识点回顾
函数形参的定义方式:
- 星号元组形参(*args) 用来收集多余的位置传参。
- 双星号字典形参(**kwargs) 用来收集多余的关键字传参。
函数传参的方式:
- 位置传参
- 拆解序列进行位置传参。
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 可以装饰任何的函数,并能够完美调用被装饰函数,且能在调用被装饰函数之前执行相应的自定义代码。