def outer(): x = 10 def inner(): #条件一、inner就是一个内部函数 print(x) #条件二、引用外部作用域的一个变量,因为x在函数外部的,所以是外部作用域的变量 return inner #结论:内部函数inner就是一个闭包 inner() #局部变量,全局无法调用
闭包(closure)是函数式编程的重要的语法结构
定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包。
闭包可以脱离环境在外部调用
装饰器(函数)
装饰器的作用就是给功能函数添加新功能。
import time def show_time(func): def inner(): start_time = time.time() func() time.sleep(1) end_time = time.time() print('spend time %s'%(end_time-start_time)) return inner @show_time #这条命令等价于 foo = show_time(foo),注意:这个show_time后面并没有加(),虽然看似没被调用,其实,show_time这个函数已经执行了。 def foo(): print('foo......') foo()
注意:1、装饰器要放在@上面,不然会报错。
2、装饰器一般用两层函数,外面一层用于将变量确定下来,里面一层函数执行整个功能。
3、其实一层函数也能为装饰器,只不过没有参数做为变动,程序就被写死了,不能做为公共接口。
带有参数的功能函数的装饰器:
import time def show_time(func): def inner(*args): #首先这里要带参数,以便将参数传进功能函数 start = time.time() func(*args) #这里面也要带参数,用来接收参数 end = time.time() print('spend time %s'%(end-start)) return inner @show_time def add(*args): total = 0 for i in args: total += i print(total) add(1,2,3,4)
装饰器参数:
import time def logger(flag): def show_time(func): def inner(): start_time = time.time() func() time.sleep(1) end_time = time.time() print('spend time %s'%(end_time-start_time)) if flag == 'true': print('日志记录') return inner return show_time @logger('true') #这里必须要加括号加参数,这才代表是一个装饰器参数,不然系统会执行foo=logger(foo),这样到show的时候就没有参数然后报错。 def foo(): print('foo.....') foo()
以上面的代码为例,带参数的装饰器其实是先执行logger("true")这个函数,这个函数执行返回show_time,这时上面其实就是@show_time,而@后面加一个函数名,就是将下面的函数名当参数传入到这个show_time()这个函数里面去,然后去执行,虽然没有调用,其实这里面也已执行了两次函数了。