>[success] # 装饰器 ~~~ 1.不用通过更改代码,进行代码 扩展的一种手段 --- 装饰器个人理解 2.使用的时候创建一个闭包的函数,然后@+闭包函数名给要装饰的函数上 ~~~ >[danger] ##### 装饰器理解案例 --- 通过装饰器创建一个代码计时器 ~~~ 1.现在有一个方法 countdown,我们想在不改变countdown 方法的基础上创建一个装饰 2.装饰器 timethis 利用闭包的原理 3.闭包原理,最外层函数作为一个函数用来接收要传入的函数,内存函数用来处理扩展当前需要扩展的函数 ~~~ ~~~ import time from functools import wraps def timethis(func): @wraps(func) def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(func.__name__,end-start) return result return wrapper @timethis def countdown(n): while n>0: n-=1 countdown(100000) 打印结果: countdown 0.0059795379638671875 ~~~ * 其实上面的代码等同于 ~~~ # 在不利用装饰器修饰的情况下直接调用等同于 n = timethis(countdown) n(100000) ~~~ >[danger] ##### 装饰器中的 wraps ~~~ 1.保存被装饰函数的一些元数据(就是一些魔法方法,个人理解就是函数指向问题) 2.下面的代码吧@wraps(func) 注释掉后打印结果wrapper,现在执行是闭包函数最内层函数 3.如果加上@wraps(func) 打印结果是 ountdown 也就是当前被装饰函数 ~~~ ~~~ import time from functools import wraps def timethis(func): # @wraps(func) def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(func.__name__,end-start) return result return wrapper @timethis def countdown(n): while n>0: n-=1 print(countdown.__name__) ~~~