【Python】闭包

引入:

通过全局变量account_amount来记录余额

并定义函数进行取款存款操作,代码如下:

python 复制代码
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)

运行结果:

复制代码
存款:+300,账户余额:300
存款:+300,账户余额:600
取款:-100,账户余额:500

尽管功能实现是OK的,但是仍有问题:

  • 代码在命名空间上(变量定义)不够干净、整洁
  • 全局变量有被修改的风险

如何解决?

  • 将变量定义在函数内部是行不通的
  • 我们需要使用闭包

我们先来看一个闭包的简单示例:

python 复制代码
def outer(logo):
    def inner(msg):
        print(f"<{logo}>{msg}<{logo}>")
    return inner

fn1 = outer("编程语言")
fn1("Python")
fn1("Java")
fn1("C++")

fn2 = outer("前端")
fn2("HTML")
fn2("CSS")
fn2("JavaScript")

运行结果:

复制代码
<编程语言>Python<编程语言>
<编程语言>Java<编程语言>
<编程语言>C++<编程语言>
<前端>HTML<前端>
<前端>CSS<前端>
<前端>JavaScript<前端>

定义双层嵌套函数,内层函数可以访问外层函数的变量

将内层函数作为外层函数的返回,此内层函数就是闭包函数

如果我们想修改外部函数的值呢?

使用nonlocal关键字

示例:

python 复制代码
def outer(num1):
    def inner(num2):
        nonlocal num1
        num1 += num2
        print(num1)
    return inner

fn = outer(10)
fn(5)
fn(3)
fn(1)

要对num1进行修改,需要用nonlocal对其进行修饰

运行结果:

复制代码
15
18
19

我们回过头来对一开始的代码进行优化:

python 复制代码
def account_create(initial_amount = 0):
    def atm(num, deposit =True):
        nonlocal initial_amount
        if deposit:
            initial_amount += num
            print(f"存款:+{num},账户余额:{initial_amount}")
        else:
            initial_amount -= num
            print(f"取款:-{num},账户余额:{initial_amount}")
    return atm

fn = account_create()
fn(300)
fn(300)
fn(100,False)

优点:

  • 无需定义全局变量即可实现:通过函数持续地访问、修改某个值
  • 闭包使用的变量的作用域在函数内,难以被错误的调用修改

缺点:

  • 由于内部函数持续引用外部函数的值,会导致这一部分内存空间不被释放,一直占用内存
相关推荐
偷光1 小时前
浏览器中的隐藏IDE: Elements (元素) 面板
开发语言·前端·ide·php
DKPT1 小时前
JVM栈溢出和堆溢出哪个先满?
java·开发语言·jvm·笔记·学习
Rock_yzh4 小时前
AI学习日记——参数的初始化
人工智能·python·深度学习·学习·机器学习
gopyer5 小时前
180课时吃透Go语言游戏后端开发6:Go语言的循环语句
开发语言·游戏·golang·循环语句
青衫客366 小时前
基于 Python 构建的安全 gRPC 服务——TLS、mTLS 与 Casbin 授权实战
python·安全·微服务
-dzk-6 小时前
【3DGS复现】Autodl服务器复现3DGS《简单快速》《一次成功》《新手练习复现必备》
运维·服务器·python·计算机视觉·3d·三维重建·三维
楼田莉子7 小时前
Qt开发学习——QtCreator深度介绍/程序运行/开发规范/对象树
开发语言·前端·c++·qt·学习
摩羯座-185690305948 小时前
爬坑 10 年!京东店铺全量商品接口实战开发:从分页优化、SKU 关联到数据完整性闭环
linux·网络·数据库·windows·爬虫·python
ACERT3338 小时前
5.吴恩达机器学习—神经网络的基本使用
人工智能·python·神经网络·机器学习
韩立学长8 小时前
【开题答辩实录分享】以《基于python的奶茶店分布数据分析与可视化》为例进行答辩实录分享
开发语言·python·数据分析