闭包

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就不会成立,这个函数也不会被创建!

Last modification:May 8, 2022
如果觉得我的内容对你有用,请随意赞赏