1 def decorator(fn): 2 def wrapper(): 3 print("询价") 4 fn() 5 print("购买成功!") 6 7 return wrapper 8 9 10 def apple(): 11 print("购买苹果") 12 13 14 def orange(): 15 print("购买橘子") 16 17 18 def potato(): 19 print("购买土豆") 20 21 22 ap = decorator(apple) 23 ap() 24 25 ora = decorator(orange) 26 ora() 27 28 po = decorator(potato) 29 po()
运行结果
(1) 装饰器相当于使用闭包函数封装公共部分的函数:
在decorator函数中, 定义一个闭包函数 wrapper, 而wrapper函数内部除了输出公共部分print("询价") print("购买成功!")
(2) decorator装饰器传入形参fn作为函数返回
参数fn传入装饰器后, 在闭包函数内部作为函数调用fn()
切记: wrapper作为闭包函数,必须返回
(3) 自定义不同函数 apple, orange, potato ...,作为实参传入装饰器
2 . 赋值给变量
ap = decorator(apple)
1 . 调用
ap()
(4)修改
直接在函数上方使用@decorator就可以调用装饰器,无需再将赋值给变量
调用函数即可
1 def decorator(fn): 2 def wrapper(): 3 print("询价") 4 fn() 5 print("购买成功!") 6 7 return wrapper 8 9 10 @decorator 11 def apple(): 12 print("购买苹果") 13 14 15 @decorator 16 def orange(): 17 print("购买橘子") 18 19 20 @decorator 21 def potato(): 22 print("购买土豆") 23 24 # ap = decorator(apple) 25 # ap() 26 # 27 # ora = decorator(orange) 28 # ora() 29 # 30 # po = decorator(potato) 31 # po() 32 apple() 33 orange() 34 potato()
(5)添加可变参数
由于调用的函数参数是不固定的,所以传入装饰器的参数必须是可变参数 *args ,其中args是自定义的,可根据实际情况改为具有实际意义的变量
(6)添加关键字参数:**kwargs中的kwargs可自定义
(5)总结
装饰器的作用其实就是封装复用的代码,并且可以将新增的公共代码写在装饰器中,避免了在函数内部扩展代码。秉承了函数的封闭性和开放性,即对修改是封闭的,对扩展是开放的 , 需要在装饰器传入可变参数和关键字参数,调用的函数才能传参。