python: 装饰器详解
一、什么是闭包?
闭包就是内层函数对外层函数(非全局)变量的引用
如何判断内层函数 __closure__ cell就是闭包
闭包: 当函数开始执行时,如果遇到了闭包,他有一个机制
: 会永远开辟一个内存空间,将闭包中的等值放入其中,不会随着函数的执行完毕而消失
name = 'jin' def wrapper(): name1 = 'king' def inner(): print(name) print(name1) inner() print(inner.__closure__) wrapper() #jin #king #(<cell at 0x00000200CC6FE858: str object at 0x00000200CC4CFF10>,)
二、装饰器
1.什么是装饰器?
语法糖@
在不改变原函数的执行情况下,为原函数添加新的功能
输入: 被装饰的函数名
输出: 内部函数名
2装饰器~~~~
2.1无参数的装饰器
import time def timer(func): def inner(): befor = time.time() ret = func() after = time.time() print("this is use time {}".format(after-befor)) return inner return inner @timer def func1(): for i in range(10): time.sleep(0.1) print(i) func1()
#this is use time 1.0047006607055664
2.带参数的装饰器
2.1
import time def timer(func): def inner(*args,**kwargs): befor = time.time() ret = func(*args, **kwargs) after = time.time() print("this is use time {}".format(after-befor)) return inner return inner @timer def func1(x): for i in range(x): time.sleep(0.1) print(i) func1(10)
2.2
def test(flag): def wrapper(func): flag1 = 0 def inner(*args,**kwargs): try: ret = func(*args,**kwargs) except Exception as e: print(e) nonlocal flag1 while flag1 < int(flag): print(flag1) flag1 += 1 inner() return inner return wrapper @test(3) def func(*args): x = "1" y = x + 2 return y func()
2.3实现缓存
注: 不加functools也可以实现
# from functools import wraps def wrapper(func): cache = {} # print(cache) # @wraps(func) def inner(*args): if args not in cache: print("ok") cache[args] = func(*args) print(func.__doc__) print(func.__name__) print(cache) return cache[args] return inner @wrapper def sum(x): ''' 求和 :param x: :return: ''' y = x+x return y @wrapper def sub(x): ''' 求差 :param x: :return: ''' y = x-1 return y x = sum(1) print(x) print('____________________') z = sum(1) print(z) print('____________________') z = sum(2) print(z) print('____________________') y = sub(1) print(y) print('____________________') y = sub(2) print(y) print('____________________')
2.3多个装饰器装饰一个函数
def wrapper1(func): def inner1(*args,**kwargs): # func = f函数名 print('wrapper1,befor func')#2 func() #3 print('wrapper1,after func') #4 return inner def wrapper2(func): # func == inner1 def inner2(*args,**kwargs): print('wrapper2, befor func') #1 func() print('wrapper2, after func') #5 return inner
@wrapper2 #f = wrapper2(f) 里面的f == inner1 外面的 f == inner2 @wrapper1 #f = wrapper1(f) 里面的f == 函数名f, 外面的f == inner1 def f(): print('in f') f()
浙公网安备 33010602011771号