参考视频
# 通过全局变量account_amount来记录余额
# 尽管功能实现是ok的,但是仍有问题:
# 代码在命名空间上(变量定义)不够干净、整洁
# 全局变量又被修改的风险
# account_amount = 0 # 账户余额
#
#
# def atm(num, deposit=True):
# global account_amount
# if deposit:
# account_amount += num
# print(f'存款:+{num},账户余额:{account_amount}')
# else:
# account_amount -= num
# print(f'取款:-{num},账户余额:{account_amount}')
#
#
# atm(300)
# atm(300)
# atm(100, False)
# 闭包,定义双层嵌套函数,在函数嵌套的前提下,内部函数使用饿狼外部函数的变量,并且外部函数返回了内部函数,
# 我们把这个使用外部函数变量的内部函数称为闭包
# 简单闭包
def outer(logo):
def inner(msg):
print(f'<{logo}>{msg}<{logo}>')
return inner
fn1 = outer('黑马程序员') # fn1变量类型是一个可以接收一个参数的函数
fn1('大家好')
"""
<黑马程序员>大家好<黑马程序员>
"""
fn2 = outer('传智教育')
fn2('大家好')
"""
<传智教育>大家好<传智教育>
"""
# 修改外部函数变量的值,需要使用nonlocal关键字修饰外部函数的变量,
# 才可在内部函数中修改它
# def outer(num1):
# def inner(num2):
# num1 += num2
# num1不能访问,闭包所引入的外部变量
def outer(num1):
def inner(num2):
nonlocal num1 # 用nonlocal声明这个外部变量
num1 += num2
print(num1)
return inner
fn = outer(10)
fn(10)
fn(20)
fn(30)
"""
20
40
70
"""
# 通过闭包实现ATM小案例
def account_create(initial_account=0):
def atm(num, deposit=True):
nonlocal initial_account
if deposit:
initial_account += num
print(f'存款,+{num},账户余额,{initial_account}')
else:
initial_account -= num
print(f'取款,{num},账户余额,{initial_account}')
return atm
atm = account_create()
atm(100)
atm(200)
atm(100, deposit=False)
"""
存款,+100,账户余额,100
存款,+200,账户余额,300
取款,100,账户余额,200
"""
# 优点,使用闭包可以让我们得到:
# 无需定义全局变量即可实现通过函数,持续的访问、修改某个值
# 闭包使用的变量的所用于在函数内,难以被错误的调用修改
#
# 缺点:
# 由于内部函数持续引用外部函数的值,所以会导致这一部分内存空间不被释放,一直占用内层
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# 其他例子
# 错误示范
# 在 Python 中,如果一个函数使用了和全局变量相同的名字且改变了该变量的值,那么该变量就会变成局部变量,
# 那么就会造成在函数中我们没有进行定义就引用了,所以会报该错误:
# cannot access local variable 'time' where it is not associated with a value
# time = 0
#
#
# def insert_time(min):
# time = time + min # 未解析的引用time
# return time
#
#
# print(insert_time(2))
# print(insert_time(10))
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# 正确示范,闭包避免了使用全局变量,此外,闭包允许将函数与其所操作的某些数据(环境)关连起来
time = 0
def study_time(time):
def insert_time(min): # 在函数内部再定义一个函数,在函数内部实现时间段相加的逻辑,字后返回最终的时间值
nonlocal time # 在函数或其他作用域中使用外层(非全局)变量
time += min
return time
return insert_time # 外层的函数study_time函数,因为在python中,函数也是对象,素以可以直接返回函数
f = study_time(time) # 调用函数study_time函数,返回的是insert_time函数,那么f其实就是相当于insert_time对象了
print(f(2)) # 2
print(time) # 0
print(f(10)) # 12 # 相当于调用insert_time(10)
print(time) # 0
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 3415226167@qq.com