闭包
构成闭包函数的基本条件:
- 一个内嵌函数:闭包函数需要在其内部定义一个或多个函数,这些内部函数被称为内嵌函数或嵌套函数。
- 内嵌函数必须引用(访问或者修改)外部函数中的变量和参数:闭包函数的内嵌函数必须引用外部函数中的变量和参数。这意味着内嵌函数可以访问和操作外部函数的变量,并且这些变量的状态在内嵌函数被调用时保留。
- 外部函数返回值必须是内嵌函数:外部函数需要返回其内部定义的内嵌函数。这样,外部函数调用后返回的是内嵌函数本身,而不是执行内嵌函数的结果。
满足这三个要素的函数就是一个闭包函数。闭包可以被视为一种封装机制。封装是面向对象编程中的一个重要概念,它允许将数据和相关的操作封装在一个单元中。
闭包的关键作用就是保存外部函数的局部变量,并且这些变量不会随着外部函数的执行结束而销毁。
下面是一个简单的计数器:
def count_a():
cnt = 0
def count_b():
nonlocal cnt
cnt += 1
print(cnt)
return count_b
f = count_a()
f()
f()
f()
其中内层函数只有对外层嵌套函数内的局部变量的访问权没有修改权,nonlocal语句用于内层函数中来获得修改权。
当然,函数也可以传参进去:
def func(x):
def d():
nonlocal x
x += 1
print(x)
return d
f = func(10)
f()
f()
f()
def outf(x):
def inf(y):
return x * y
return inf
a = outf(5)
print(a)
print(a(10))
print(a(5))
装饰器
装饰器允许在不修改原始函数代码的情况下,通过包装函数来扩展或修改其行为。本质上就是个闭包。
用法就是把需要装饰的函数作为闭包的内置函数,在外部函数中实现装饰。
大概就像这样:
def mag(x):# 装饰器
def cg():
res = x() # 函数调用
print('变成捧腹大笑的奶龙')
print('变身结束')
return res #这里是返回原函数返回值的,无返回值时可以不写
return cg
def person():
print('一个普通的人')
f = mag(person)
f() #函数调用
然后发现写一f = mag(person)很麻烦,于是有一个语法糖:我们将要装饰的函数上一行写@装饰器名称 ,这样直接调用原函数是会自动用上装饰器,相当于程序加了一person = mag(person)
def mag(x):# 装饰器
def cg():
x() # 函数调用
print('变成捧腹大笑的奶龙')
print('变身结束')
return x #这里可以不写
return cg
@mag
def person():
print('一个普通的人')
person()
