python 装饰器-初识
一、装饰器的形成过程
1.函数无参数,无返回值
import time def f1(): # 无参数,无返回值 time.sleep(1) print("Hello, World!") def timer(f): # f 是函数名 def inner(): # 闭包 start = time.time() f() end = time.time() total = end - start print(total) return inner f1 = timer(f1) # 调用timer()函数,获取inner函数名指向的内存地址的返回值 f1()
2.函数有返回值,无参数
import time def f1(): # 无参数,有返回值 time.sleep(1) print("Hello, World!") return True def timer(f): # f 是函数名 def inner(): # 闭包 start = time.time() ret = f() end = time.time() total = end - start print(total) return ret return inner f1 = timer(f1) # 调用timer()函数,获取inner函数名指向的内存地址的返回值 ret = f1() print(ret)
3.函数有参数,有返回值
def f1(a, **kwargs): # 参数,返回值 *args和**args可以组成任意类型的参数 time.sleep(1) print("Hello, World!", a, kwargs) return "abc" def timer(f): # f 是函数名 def inner(*args, **kwargs): # 闭包 start = time.time() ret = f(*args, **kwargs) end = time.time() total = end - start print(total) return ret return inner f1 = timer(f1) # 调用timer()函数,获取inner函数名指向的内存地址的返回值 ret = f1(1, name='tom') print(ret)
二、装饰器的作用
在不改变函数调用方式的情况下,在原函数的前后添加功能
三、开放封闭原则
开放:对扩展开放
封闭:对修改封闭
这是装饰器开发的原则
四、语法糖
简化代码
import time def timer(f): # f 是函数名 def inner(*args, **kwargs): # 闭包 start = time.time() ret = f(*args, **kwargs) end = time.time() total = end - start print(total) return ret return inner @timer # f1 = timer(f1),语法糖简化代码 def f1(a, **kwargs): # 参数,返回值 *args和**args可以组成任意类型的参数 time.sleep(1) print("Hello, World!", a, kwargs) return "abc" ret = f1(1, name='tom') print(ret)
五、装饰器的固定模式
def wrapper(f): # 装饰器 def inner(*args, **kwargs): # 在原函数(被装饰)前增加的功能 ret = f(*args, **kwargs) # 被装饰的函数 # 在原函数(被装饰)后增加的功能 return ret return inner @wrapper # f1 = wrapper(f1) def f1(*args, **kwargs): print("Hello World!", args, kwargs) return args ret = f1('a', 'b', name='tom') # f1指向的内存地址是inner指向的内存地址 print(ret)
巧记:1.先定义函数,再定义内部函数,返回内部函数的函数名
2.内部函数内放被装饰的函数,传进被装饰函数的函数名
3.被装饰的参数需要参数和返回值
PS:参数的传递:接收聚合,调用打散