python 闭包

发布时间 2023-08-08 08:39:25作者: steve.z
#
#   py_closure.py
#   py_learn
#
#   Created by Z. Steve on 2023/8/8 07:17.
#
# 闭包:
# 1. 概念相关
# 闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。
# 换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。 在JavaScript 中,闭包会随着函数的创建而被同时创建。
# 内部函数在执行前,从外部函数返回。
# 闭包共享相同的函数定义,但是保存了不同的词法环境。
# 闭包很有用,因为它允许将函数与其所操作的某些数据(环境)关联起来。这显然类似于面向对象编程。
# 在面向对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。
# 如果不是某些特定任务需要使用闭包,在其他函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响。
# 外部函数内存空间持续保留不会被释放
# 闭包内访问的外部变量不会一直存在,而且不能被外部其他人访问到
# 反向思考:在函数外部如何才能访问到函数内的局部变量?通过闭包。
# 在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。(将外层函数的函数内部与函数外部链接起来的桥梁——闭包)
# 2. 使用场景
# 2.1 在函数外部使用函数内部的变量
# 2.2 将函数始终保持在内存中


# 1. 简单的闭包演示代码
def create_closure(en):
    def func(cn):
        print(en + cn)

    return func


# 3. 通过 nonlocal 关键字修饰
def create_closure_nonlocal(en):
    def func(cn):
        nonlocal en  # 通过 nonlocal 关键字修饰外部变量 en 即可使在 func 内部修改 en 变量
        en = en + "hhhhhhhhh"
        print(en + cn)

    return func


# 3. 实现银行存取款案例
def create_bank_account(balance=0):
    # num 表示本次存取款金额. deposit = True 表示存钱; deposit = False 表示取钱;
    def atm(num, deposit=True):
        nonlocal balance
        if deposit:
            balance += num
            print(f"存款 +{num} 操作完成。余额:{balance}")
        else:
            balance -= num
            print(f"取款 -{num} 操作完成。余额:{balance}")

    return atm


if __name__ == "__main__":
    # fn = create_closure_nonlocal("data info")
    # fn("中文")

    fn = create_bank_account(0)
    fn(100)
    fn(50)
    fn(500)
    fn(300, False)
    fn(100, False)
    fn(10)