闭包:延伸了作用域的函数,包含函数定义体中引用,但是不在定义体中定义的非全局变量。
有3个要素——
1:嵌套函数;2:内部函数引用了外部函数的局部变量;3:外部函数的返回值是内部函数的引用。
# 例子,来自《流畅的python》
def make_averager():
series=[]
def averager(new_value):
series.append(new_value)
avg = sum(series)/len(series)
return avg
return averager
#------------------------------------------
avg = make_averager()
s1 = avg(10)
print(s1)
s2 = avg(11)
print(s2)
s3 = avg(12)
print(s3)
装饰器的2个特性——
1:把被装饰的函数替换成其他函数;2:装饰器在加载模块时立即执行。
被装饰的函数的定义体和调用方式不会发生改变。
#例子1:
import time
def outer(func):
def wrapper():
print('i am inner')
print('start time is :' + str(time.time()))
func()
print('end time is :' + str(time.time()))
# 装饰器加载时执行,所以会最先打印。
print('i am outer')
return wrapper
@outer
def foo():
print('foo......')
time.sleep(3)
foo()
print(foo) #foo的类型是outer的返回值
# 例子2:多层装饰,本质相当于层层装饰:deco2(deco1(foo))
def deco1(func):
print('func 1 in')
def wrapper1():
print('wrap1 in')
func()
print('wrap1 out')
print('func 1 out')
return wrapper1
def deco2(func):
print('func 2 in')
def wrapper2():
print('wrap2 in')
func()
print('wrap2 out')
print('func 2 out')
return wrapper2
@deco1
@deco2
def foo():
print('foo')
# 例子3,带参数的装饰器。
# 带参数的装饰器
def deco(params): # params 为需要传入的参数
print('floor1')
def inner(func):
print('floor2')
def warp(*args, **kwargs):
print('floor3')
print('装饰开始')
for i in range(params):
func(*args, **kwargs)
print('装饰结束')
print('out3')
print('out2')
return warp
print('out1')
return inner
@deco(5) # 这个就是生成一个函数warp指向demo
def demo():
print('ok')
demo()