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
相关推荐
PiaoKe___41 分钟前
云手机原理与 Python 自动化实战:ADB 批量控制、任务调度与落地建议
服务器·arm开发·python·自动化
Gigavision7 小时前
基于BUAA-MIHR数据集的噪声解耦对比学习算法
人工智能·python·深度学习·算法
IPdodo_7 小时前
跨境 API 调用不稳定怎么办:出口、超时重试与链路监控的实践
网络·python·网络协议
Madison-No78 小时前
搭建项目测试环境
linux·运维·服务器·python
计算机编程-吉哥8 小时前
YOLO26 vs YOLO11 vs YOLOv8:深度学习咖啡果实成熟度分割系统【计算机毕业设计选题推荐】
人工智能·python·深度学习·yolo·django·毕业设计
大衛說9 小时前
11 · 异常处理与日志
python
auto_go9 小时前
Python 实战指南(7)——账本动不动就崩?先把“魔法字符串”和“裸报错”干掉
python
Beyond_System|系统之外9 小时前
【学编程】Python基础编程题100道(21-60)
开发语言·python·算法
根目录下的猫9 小时前
RK3588适配的轻量级AI模型推荐
人工智能·后端·python·目标检测
wno70410 小时前
Spring Security权限控制
java·python·spring