Python中的闭包和装饰器

一、闭包的定义与实例

1.1 闭包的定义与介绍

在Python实际开发过程中,调用函数过程中,函数内定义的变量都销毁了。此时由于业务需求可能需要保存函数内的这个变量,调用这个变量进行一系列操作。为了解决这个问题,引入闭包这个概念。

闭包的定义:

在函数其那套的壳体下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数。这个使用外部函数变量的内部函数的过程称为闭包

1.2 闭包的构成条件

  • 通过闭包的定义,此时的闭包形成条件如下:
  • 函数嵌套(函数里再次定义函数)。
  • 内部函数使用了外部函数的变量(包括外部函数的参数)。
  • 外部函数返回了内部函数。

1.3 闭包实例

python 复制代码
# 定义一个外部函数
def func_out(num1):
    # 定义一个内部函数
    def func_inner(num2):
        # 内部函数使用了外部函数的变量(num1)
        result = num1 + num2
        print("结果是:", result)
    # 外部函数返回了内部函数,这里返回的内部函数就是闭包
    return func_inner

# 创建闭包实例    
f = func_out(1)
# 执行闭包
f(2)
f(3)

运行结果如下:

结果是:3

结果是:4

通过以上结果,不妨可以看出, 由于这里使用的闭包的设计理念,每次调用程序时都保存了外部函数内的变量num1,此时的赋值都是独立且不互相影响的。综上所述,闭包可以保存外部函数内的变量,不会随着外部函数的调用结束而销毁。

1.4 闭包语法

python 复制代码
#外部函数
def test1(a):
    b = 10
    #内部函数
    def test():
        #内部函数使用了外部函数的变量或者参数
        print(a,b)
    return test2

tips:当返回的内部函数使用了外部函数的变量就形成了闭包;闭包可以对外部函数的变量进行保存;修改闭包内使用的外部函数变量使用nonlocal关键字来完成。

二、装饰器的定义与实例

2.1 装饰器的定义

装饰器是一个设计模式,通常用于不修改函数内容时增加函数功能的场景下。在Python中,装饰器通常用于日志记录、性能测试、十五处理等场景。装饰器的本质是一个函数,它接受一个函数作为参数并返回一个新的函数。

2.2 装饰器的语法糖

Python中的装饰器可以通过@符号来简介地运用,实例如下:

python 复制代码
def check(fn):
    def proxy():
        print("请先登录!")
        fn()
    return proxy

@check
def comment():
    print("该商品好!")
comment()

装饰器的执行流程:

  • @ check将comment函数作为参数传递给check函数。
  • check函数返回一个新的函数proxy,它在调用comment之前增加了打印功能。
  • 当调用comment()时,实际上是调用了proxy函数,,首先打印"请先登录!",然后调用原始的comment函数。

三、闭包与装饰器结合

闭包和装饰器可以结合使用,以便于实现更复杂的功能。即:可以使用闭包来创建具有私有状态的装饰器

实例:init_conversation函数返回了一个内部函数get_conversation的引用,这个内部函数记住了info变量的值。每次调用init_conversation都会创建一个新的闭包,它捕获不同的info值。

python 复制代码
def init_conversation(info):
    def get_conversation(name):
        print(name + ":" + info)
    return get_conversation  # 返回内部函数的引用

final_conversation = init_conversation("不在你回我干嘛!")
final_conversation("张三")  # 打印 "张三:不在你回我干嘛!"

final_conversation = init_conversation("不想搭理你!")
final_conversation("李四")  # 打印 "李四:不想搭理你!"

四、总结

闭包和装饰器是Python中强大的功能,它们允许我们在不修改原始函数代码的情况下增加新的行为。闭包通过捕获外部函数的变量来实现状态的保持,而装饰器则通过函数包装来增强函数功能。理解并掌握这两种技术,可以帮助我们编写更加模块化、可重用和易于维护的代码。

相关推荐
码云数智-园园17 分钟前
微服务架构下的分布式事务:在一致性与可用性之间寻找平衡
开发语言
吴佳浩28 分钟前
GPU 编号进阶:CUDA\_VISIBLE\_DEVICES、多进程与容器化陷阱
人工智能·pytorch·python
C++ 老炮儿的技术栈34 分钟前
volatile使用场景
linux·服务器·c语言·开发语言·c++
hz_zhangrl34 分钟前
CCF-GESP 等级考试 2026年3月认证C++一级真题解析
开发语言·c++·gesp·gesp2026年3月·gespc++一级
Liu628881 小时前
C++中的工厂模式高级应用
开发语言·c++·算法
IT猿手1 小时前
基于控制障碍函数的多无人机编队动态避障控制方法研究,MATLAB代码
开发语言·matlab·无人机·openclaw·多无人机动态避障路径规划·无人机编队
全栈凯哥1 小时前
18.Python中的导入类完全指南
python
AI科技星1 小时前
全尺度角速度统一:基于 v ≡ c 的纯推导与验证
c语言·开发语言·人工智能·opencv·算法·机器学习·数据挖掘
sunwenjian8861 小时前
Java进阶——IO 流
java·开发语言·python
波特率1152002 小时前
const关键字与函数的重载
开发语言·c++·函数重载