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

相关推荐
应用市场1 小时前
构建自定义命令行工具 - 打造专属指令体
开发语言·windows·python
东方佑1 小时前
从字符串中提取重复子串的Python算法解析
windows·python·算法
Dfreedom.2 小时前
一文掌握Python四大核心数据结构:变量、结构体、类与枚举
开发语言·数据结构·python·变量·数据类型
一半烟火以谋生2 小时前
Python + Pytest + Allure 自动化测试报告教程
开发语言·python·pytest
虚行2 小时前
C#上位机工程师技能清单文档
开发语言·c#
小羊在睡觉3 小时前
golang定时器
开发语言·后端·golang
CoderCodingNo3 小时前
【GESP】C++四级真题 luogu-B4068 [GESP202412 四级] Recamán
开发语言·c++·算法
叶子丶苏3 小时前
第八节_PySide6基本窗口控件_按钮类控件(QAbstractButton)
python·pyqt
Larry_Yanan3 小时前
QML学习笔记(四十四)QML与C++交互:对QML对象设置objectName
开发语言·c++·笔记·qt·学习·ui·交互
百锦再3 小时前
对前后端分离与前后端不分离(通常指服务端渲染)的架构进行全方位的对比分析
java·开发语言·python·架构·eclipse·php·maven