14.Python闭包、装饰器

1.闭包

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

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

python 复制代码
# 一般实现
account_amount = 0
def atm(num,deposit=True):
    global account_amount
    if deposit:
        account_amount += num
        print(f"存款{num}元,余额为:", account_amount)
    else:
        if num > account_amount:
            print("取款金额超出余额")
            return
        account_amount -= num
        print(f"取款{num}元,余额为:",account_amount)

atm(100)
atm(200)
atm(200,False)
atm(200,False)
闭包实现 复制代码
def  atm (account_amount = 0): # 外部函数
    def inner(num,deposit=True): # 内部函数
        nonlocal account_amount #需要使用nonlocal关键字修饰外部函数的变量才可在内部函数中修改它
        if deposit:
            account_amount += num
            print(f"存款{num}元,余额为:", account_amount)
        else:
            if num > account_amount:
                print(f"余额不足")
                return inner
            account_amount -= num
            print(f"取款{num}元,余额为:",account_amount)
    return inner # 返回内部函数

fn=atm()
fn(100)
fn(200)
fn(200,False)
fn(200,False)

优点,使用闭包可以让我们得到:

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

缺点:由于内部函数持续引用外部函数的值,所以会导致这一部分内存空间不被释放,一直占用内存

装饰器

装饰器其实也是一种闭包, 其功能就是在不破坏目标函数原有的代码和功能的前提下,为目标函数增加新功能。

scss 复制代码
def sleep():
    import random
    import time
    print("睡眠中...")
    time.sleep(random.randint(1, 5))

print("我要睡觉了")
sleep()
print("我起床了")

希望给sleep函数,增加一个功能:

在调用sleep前输出:我要睡觉了

在调用sleep后输出:我起床了

定义一个闭包函数, 在闭包函数内部: 执行目标函数 并完成功能的添加

装饰器 复制代码
def outer(func):
    def inner():
        print("开始执行")
        func()
        print("结束执行")
    return inner

fn=outer(sleep)
fn()

装饰器的语法糖写法

使用@outer

定义在目标函数sleep之上

python 复制代码
def outer(func):
    def inner():
        print("开始执行")
        func()
        print("结束执行")
    return inner

# fn=outer(sleep)
# fn()

@outer
def sleep():
    import random
    import time
    print("睡眠中...")
    time.sleep(random.randint(1, 5))

sleep() #这里本质还是调用的inner
相关推荐
第九序言T9 小时前
Python 数据处理进阶(十八)批量处理同结构文件:一个文件夹一次跑完
开发语言·python·自动化·pandas·数据处理
Java后端的Ai之路9 小时前
CAS并发控制-从CPU指令到企业级乐观锁
vue.js·人工智能·python·cas·乐观锁
qq_426003969 小时前
UI自动化高频次登录login限流解决方案
python·ui·自动化
Sakura_j_h_10 小时前
EasyEDA PCB 快速设计Skills
c++·python·github
quantdash_cc11 小时前
如何验证历史行情的交易日期是否完整覆盖研究区间?
python·数据分析·pandas·量化交易·股票数据·quantdash
I Am a robert girl11 小时前
当智能体学会“串通”:从长程交互中读懂涌现式合谋
python·多智能体系统·多智能体协作·llm agent·涌现式合谋·对齐问题·激励机制设计
云和数据.ChenGuang12 小时前
光哥说Python RAG 系统需要哪些评估指标:从检索到生成的全链路评测指南
网络·人工智能·python·算法·langchain
专注仿真12 小时前
线性回归和逻辑回归算法详解
开发语言·人工智能·python·大模型训练·控制算法
wflynn13 小时前
GitHub 今日推荐|Edge0:让大号 MoE 模型在一台 Mac 上流式跑起来
python·开源·github
2601_9679801113 小时前
python之用scapy分层解析pcap报文(Ethernet帧、IP数据包、TCP数据包、UDP数据包、Raw数据包)
python·scapy·pcap·协议分析·网络数据包