1.闭包
定义双层嵌套函数, 内层函数可以访问外层函数的变量
将内存函数作为外层函数的返回,此内层函数就是闭包函数
python
# 一般实现
account_amount = 0
def atm(num,deposit=True):
global account_amount
if deposit:
account_amount += num
print(f"存款{num}元,余额为:", account_amount)
else:
if num > account_amount:
print("取款金额超出余额")
return
account_amount -= num
print(f"取款{num}元,余额为:",account_amount)
atm(100)
atm(200)
atm(200,False)
atm(200,False)
闭包实现
def atm (account_amount = 0): # 外部函数
def inner(num,deposit=True): # 内部函数
nonlocal account_amount #需要使用nonlocal关键字修饰外部函数的变量才可在内部函数中修改它
if deposit:
account_amount += num
print(f"存款{num}元,余额为:", account_amount)
else:
if num > account_amount:
print(f"余额不足")
return inner
account_amount -= num
print(f"取款{num}元,余额为:",account_amount)
return inner # 返回内部函数
fn=atm()
fn(100)
fn(200)
fn(200,False)
fn(200,False)
优点,使用闭包可以让我们得到:
- 无需定义全局变量即可实现通过函数,持续的访问、修改某个值
- 闭包使用的变量的所用于在函数内,难以被错误的调用修改
缺点:由于内部函数持续引用外部函数的值,所以会导致这一部分内存空间不被释放,一直占用内存
装饰器
装饰器其实也是一种闭包, 其功能就是在不破坏目标函数原有的代码和功能的前提下,为目标函数增加新功能。
scss
def sleep():
import random
import time
print("睡眠中...")
time.sleep(random.randint(1, 5))
print("我要睡觉了")
sleep()
print("我起床了")
希望给sleep函数,增加一个功能:
在调用sleep前输出:我要睡觉了
在调用sleep后输出:我起床了
定义一个闭包函数, 在闭包函数内部: 执行目标函数 并完成功能的添加
装饰器
def outer(func):
def inner():
print("开始执行")
func()
print("结束执行")
return inner
fn=outer(sleep)
fn()
装饰器的语法糖写法
使用@outer
定义在目标函数sleep之上
python
def outer(func):
def inner():
print("开始执行")
func()
print("结束执行")
return inner
# fn=outer(sleep)
# fn()
@outer
def sleep():
import random
import time
print("睡眠中...")
time.sleep(random.randint(1, 5))
sleep() #这里本质还是调用的inner