闭包
def 求平均值():
求和列表=[]
#这里闭包了!
#求和列表变成了一个“自由变量”
def 真正的求和函数(x):
求和列表.append(x)
return sum(求和列表)/len(求和列表)
return 真正的求和函数
实例化1=求平均值()
求平均值
<function __main__.求平均值()>
求平均值()
<function __main__.求平均值.<locals>.真正的求和函数(x)>
实例化1
<function __main__.求平均值.<locals>.真正的求和函数(x)>
实例化1(1)
实例化1(2)
实例化1(3)
2.0
列表是可变对象
对于不可变对象,我们用nonlocal声明,用法等同于global
def 求平均值2():
总和=0
个数=0
#这里闭包了!
#求和列表变成了一个“自由变量”
def 真正的求和函数(x):
nonlocal 总和,个数
总和=总和+x
个数+=1
return 总和/个数
return 真正的求和函数
实例化2=求平均值2()
实例化2
<function __main__.求平均值2.<locals>.真正的求和函数(x)>
实例化2(1)
实例化2(2)
实例化2(3)
2.0
装饰器概念来了!
我们借助闭包,联想一下,我们把函数a用一个b装饰器装饰一下
def b(func):
'''func是一个函数对象,被装饰的函数对象'''
print(func,'被装饰了')
#装饰完后,我们当然要原封不动的还回去
return func
@b
def a():
print('我被调用了一次')
<function a at 0x000001904023B2F0> 被装饰了
a()
我被调用了一次
由此可见,装饰器在函数定义的时候 执行!
def a():
print('我被调用了一次')
b(a)
a()
<function a at 0x0000027434097950> 被装饰了
我被调用了一次
而我们的flask的app.route就是参数化的装饰器
或许这样你就可以进一步理解其本质了...
装饰器的作用在于强调这个函数,它可以叠加使用,这样就会按照一定的顺序,需要注意的是,如果你的装饰器没有return函数对象,那么这个def就不会成立,这个函数也不会被创建!