1.闭包特性
#在outer函数内定义的x变量,在outer执行完之后,任然可以访问x,这种现象就是闭包的特性 def outer(): x = 1 def inner(): print(x) return inner f = outer() #闭包函数inner()被加载到内存中,而不会被执行 f() #执行inner()
2.装饰器
装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
3.一张图说明装饰器的用法
foo=show_time(foo)其实是把wrapper引用的对象引用给了foo,而wrapper里的变量func之所以可以用,就是因为wrapper是一个闭包函数
@show_time帮我们做的事情就是当我们执行业务逻辑foo()时,执行的代码由粉框部分转到蓝框部分
装饰器在Python使用如此方便都要归因于Python的函数能像普通的对象一样能作为参数传递给其他函数,可以被赋值给其他变量,可以作为返回值
4.带参数的被装饰函数
1 import time 2 3 def show_time(func): 4 5 def wrapper(*args,**kwargs): 6 start_time=time.time() 7 func(*args,**kwargs) 8 end_time=time.time() 9 print('spend %s'%(end_time-start_time)) 10 11 return wrapper 12 13 @show_time #add=show_time(add) 14 def add(*args,**kwargs): 15 16 time.sleep(1) 17 sum=0 18 for i in args: 19 sum+=i 20 print(sum) 21 22 add(2,4,8,9)
5.带参数的装饰器
通过在装饰器函数外层再封装一层函数,并且该函数的返回值是装饰器函数
1 import time 2 3 def time_logger(flag=0): 4 5 def show_time(func): 6 7 def wrapper(*args,**kwargs): 8 start_time=time.time() 9 func(*args,**kwargs) 10 end_time=time.time() 11 print('spend %s'%(end_time-start_time)) 12 13 if flag: 14 pass 15 16 return wrapper 17 18 return show_time 19 20 @time_logger(1) 21 def add(*args,**kwargs): 22 time.sleep(1) 23 sum=0 24 for i in args: 25 sum+=i 26 print(sum)