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

相关推荐
DataLaboratory1 小时前
Python爬取百度地图-前端直接获取
爬虫·python·百度地图
Turnsole_y3 小时前
pycharm自动化测试初始化
python·selenium
R-G-B4 小时前
【02】C#入门到精通——C# 变量、输入/输出、类型转换
开发语言·c#·c# 变量·c#输入/输出·c#类型转换
星河队长4 小时前
C# 软件加密方法,有使用时间限制,同时要防止拷贝
开发语言·c#
史迪奇_xxx4 小时前
10、一个简易 vector:C++ 模板与 STL
java·开发语言·c++
2301_801252224 小时前
Java中的反射
java·开发语言
Kiri霧4 小时前
Rust开发环境搭建
开发语言·后端·rust
weixin-a153003083164 小时前
[数据抓取-1]beautifulsoup
开发语言·python·beautifulsoup
AI量化投资实验室4 小时前
15年122倍,年化43.58%,回撤才20%,Optuna机器学习多目标调参backtrader,附python代码
人工智能·python·机器学习
倔强青铜三5 小时前
苦练Python第67天:光速读取任意行,linecache模块解锁文件处理新姿势
人工智能·python·面试