【蟒蛇】20、闭包-学Python黑马程序员个人笔记

  1. 参考视频

参考视频

黑马程序员python教程,8天python从入门到精通

# 通过全局变量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
资源 相册