【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)

优点:

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

缺点:

  • 由于内部函数持续引用外部函数的值,会导致这一部分内存空间不被释放,一直占用内存
相关推荐
郑州光合科技余经理14 小时前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo12314 小时前
matlab画图工具
开发语言·matlab
dustcell.14 小时前
haproxy七层代理
java·开发语言·前端
norlan_jame14 小时前
C-PHY与D-PHY差异
c语言·开发语言
多恩Stone15 小时前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
QQ40220549615 小时前
Python+django+vue3预制菜半成品配菜平台
开发语言·python·django
百锦再15 小时前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip
QQ51100828515 小时前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php
QQ_196328847515 小时前
Python-flask框架西山区家政服务评价系统网站设计与开发-Pycharm django
python·pycharm·flask
遥遥江上月15 小时前
Node.js + Stagehand + Python 部署
开发语言·python·node.js