Python 深入学习局部函数和闭包函数

news2024/11/26 14:24:28

目录

局部函数与闭包函数的关联

变量捕获与状态保留

应用场景的交集与差异

闭包的本质

局部函数示例

闭包函数示例



局部函数和闭包函数之间存在着密切的联系,同时也有一些本质的区别。

局部函数与闭包函数的关联

局部函数(Nested Function)

也称嵌套函数,指的是在另一个函数内部定义的函数。它作为外部函数的一部分,只能在外部函数的上下文中被调用和访问。

局部函数可以访问外部函数的局部变量和参数,但通常情况下,一旦外部函数执行完毕,这些局部变量就会被销毁。

闭包函数(Closure)

实际上是一种特殊类型的局部函数,它能够“记住”并访问其外部函数的局部变量和参数,即使在外部函数已经返回之后。

闭包的关键在于它维持了对外部变量的引用,从而能够在外部函数的生命周期结束后继续访问这些变量。

变量捕获与状态保留

局部函数通常不涉及对外部作用域变量的长期保留。它只是简单地借用外部变量的值进行计算或处理,当外部函数执行完毕,局部变量的生命周期也就结束了。

闭包函数通过创建一个引用链条,使得外部函数的局部变量不会被垃圾回收机制回收,即使外部函数已经执行完毕。这就允许闭包在后续的调用中继续访问和修改这些外部变量,从而实现了状态的保留。

应用场景的交集与差异

交集:两者都可以用来实现代码的模块化,通过将相关的操作封装在一起来提高代码的可读性和可维护性。局部函数和闭包函数都能帮助程序员更好地组织代码结构,减少全局变量的使用,从而降低命名冲突的风险。

差异:闭包特别适用于需要在不同时间点访问和修改共享状态的场景,如计数器、缓存管理、装饰器等。而局部函数更多用于逻辑分段,将大块的代码分解为更小、更易于管理的部分,不一定涉及状态的持久化。

闭包的本质

闭包可以视为局部函数的一种扩展,它利用了作用域链和变量生命周期的特性,提供了一种在函数间传递状态和数据的方式。闭包的核心价值在于它打破了常规的变量作用域限制,使得函数可以拥有“记忆”,这在函数式编程和某些特定的设计模式中极为有用。

局部函数示例

这里我们定义一个函数,该函数内部包含一个局部函数,用于执行某个特定计算任务,但不涉及状态的保留。

def outer_function(x):
    """
    这是一个包含局部函数的外部函数。
    它定义了一个局部函数inner_function来执行计算。
    """
    def inner_function(y):
        """这是一个局部函数,用于计算x和y的和。"""
        return x + y  # 访问了外部函数的变量x,并与传入的y相加
    
    result = inner_function(10)  # 调用局部函数并传递参数
    return result

# 调用外部函数
output = outer_function(5)
print(output)  # 输出结果为15

在这个例子中,inner_function是一个局部函数,它只能在outer_function内部被访问和调用。它能够访问外部函数outer_function的参数x,但是当outer_function执行完毕后,inner_function就不再可用。

闭包函数示例

通过一个闭包的例子来展示如何在函数执行结束后仍然保留对外部变量的访问。

def counter_factory(start):
    """
    这个工厂函数返回一个闭包函数。
    闭包函数能够记住start的值,并在此基础上进行计数。
    """
    count = start  # 这个变量被闭包记住

    def counter():
        """闭包函数,每次调用都返回递增的计数。"""
        nonlocal count
        count += 1
        return count

    return counter  # 注意这里返回的是counter函数本身,而不是调用它

# 创建一个从1开始的计数器
counter1 = counter_factory(1)

print(counter1())  # 输出2
print(counter1())  # 输出3
print(counter1())  # 输出4

# 创建另一个从10开始的计数器,演示闭包独立保存状态的能力
counter2 = counter_factory(10)

print(counter2())  # 输出11
print(counter2())  # 输出12

图片

在这个例子中,counter_factory函数返回了一个闭包函数counter。虽然counter函数在counter_factory执行完毕后仍然可用,但它“记得”了创建时start的值,并且每次调用都会基于这个初始值进行计数,展示了闭包的“记忆”特性。每个由counter_factory创建的闭包实例都保留了自己的状态,互不影响。

字典键值对找不到?Python魔法方法__missing__来帮你!-CSDN博客
Humanize,一个很有人情味的 Python 库_python humanize-CSDN博客
Python自定义接口,也能玩得这么花-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1852171.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

git 拉下来的项目,出现“加载失败”的解决方法

现象: 1、对加载失败的项目,尝试重新加载 解决思路:根据上面的提示,打开F盘对应的 .vcxproj文件,查看里面关于opencv454.props的内容 先删了,后面再补 2、当前的工作重点是消除加载失败的情况,…

VBA技术资料MF165:关闭当前打开的所有工作簿

我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解&#…

RabbitMQ延时队列(实现定时任务)

消息的TTL(Time To Live)就是消息的存活时间。 RabbitMQ可以对队列和消息分别设置TTL。 对队列设置存活时间,就是队列没有消费者连着的保留时间。 对每一个单独的消息单独的设置存活时间。超过了这个时间,我们认为这个消息就死了,称之为死…

高速缓存存储器(Chche)

为了解决CPU和主存之间速度不匹配的问题,计算机系统中引入了高速缓存(Chche)的概念。 基本想法:使用速度更快但容量更小、价格更高的SRAM制作一个缓冲存储器,用来存放经常用到的信息;这样一来,…

csdn上传源码资源卖钱能买房买车吗?每天最高收入200-500?

csdn上传源码卖钱能买房买车吗,最高收入200-500? 作者收入日榜 不***孩 收益617.32元 程***妍 收益534.56元 s***n 收益323.71元 盈***客 收益315.05元 极***计 收益284.17元

K8S - 实现statefulset 有状态service的灰度发布

什么是灰度发布 Canary Release 参考 理解 什么是 滚动更新,蓝绿部署,灰度发布 以及它们的区别 配置partition in updateStrategy/rollingUpdate 这次我为修改了 statefulset 的1个yaml file statefulsets/stateful-nginx-without-pvc.yaml: --- apiVe…

Kimichat使用案例027:有效使用 kimichat 的15个高级技巧

文章目录 一、明确具体:表达清晰、避免使用模糊措辞。二、提供背景信息:提供相关的细节和背景信息。三、每次只问一个问题四、设定明确的标准五、要求解释六、管理期望七、确定问题类型八、调整语言水平九、提供范例十、及时提供反馈十一、明确对话角色十二、 保持对话的连贯…

Java程序之百鸡百钱问题

题目: 百钱买百鸡的问题算是一套非常经典的不定方程的问题,题目很简单:公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱,用100文钱买一百只鸡,其中公鸡,母鸡,小鸡都必须要有,…

如何设置MySQL远程访问权限?

MySQL是一种流行的关系型数据库管理系统,它广泛应用于各种Web应用程序和数据驱动的应用中。在默认情况下,MySQL只允许本地访问,为了能够从远程服务器或客户端访问MySQL数据库,我们需要进行一些额外的设置和配置。 安装和配置MySQ…

git拉取gitee项目到本地

git安装等不做赘述。 根据需要选择不同操作 1.只是单纯拉取个项目,没有后续的追踪等操作 不需要使用git init初始化本地文件夹 新建一个文件夹用于存储项目,右键选择 git bash here 会出现命令行窗口 如果像我一样,只是拉取个项目作业&…

vuejs3用gsap实现动画

效果 gsap官网地址&#xff1a; https://gsap.com/ 安装gsap npm i gsap 创建Gsap.vue文件 <script setup> import {reactive, watch} from "vue"; import gsap from "gsap"; const props defineProps({value:{type:Number,default:0} }) cons…

CAD二次开发(11)-在用C#进行CAD开发SQLite和SqlSugar的使用

1. System.Data.SQLite的使用 1.1 包的引入 利用 Nuget引入其相关包 1.2 App.config配置引入到CAD 因为我们当前的项目是类库项目&#xff0c;需要依托于宿主程序才可以运行&#xff0c;所以我们就得需要将SQLite自动生成的App.config里面的部分配置移植到CAD的配置文件中…

从工具产品体验对比spark、hadoop、flink

作为一名大数据开发&#xff0c;从工具产品的角度&#xff0c;对比一下大数据工具最常使用的框架spark、hadoop和flink。工具无关好坏&#xff0c;但人的喜欢有偏好。 目录 评价标准1 效率2 用户体验分析从用户的维度来看从市场的维度来看从产品的维度来看 3 用户体验的基本原则…

双叒叕-一个-Android-MVVM-组件化架构框架?

LifecycleViewModelLiveDataViewBindingAndroid KTXOkHttp:网络请求Retrofit:网络请求MMKV:腾讯基于 mmap 内存映射的 key-value 本地存储组件Glide:快速高效的Android图片加载库ARoute:阿里用于帮助 Android App 进行组件化改造的框架 —— 支持模块间的路由、通信、解耦BaseR…

Instagram APIj接口——快速获取Ins帖子媒体内容下载链接

一、引言 在社交媒体蓬勃发展的今天&#xff0c;Instagram已成为用户分享照片、视频和精彩瞬间的首选平台。然而&#xff0c;对于很多用户来说&#xff0c;想要保存或分享Instagram上的精彩内容却常常遇到困扰。为了解决这个问题&#xff0c;我们精心打造了一款全新的Instagra…

yolov8训练初体验

最近在爬一些数据&#xff0c;有些网址的验证码比较难搞&#xff0c;于是使用yolov8来解决。 一、数据打标签并转为txt 使用的软件为X-AnyLabeling。内置各种模型&#xff0c;方便打标。 打标完成后由于是json格式&#xff0c;所以我们使用python转换即可 import json import…

51单片机STC89C52RC——5.1 LCD1602液晶显示屏

目录 目的 一&#xff0c;STC单片机模块 二&#xff0c;LCD1602 2.1 模块简介 2.2 针脚 2.3 DDRAM地址与显示器对应关系 2.4 标准字库表 2.5 常用指令 2.6 读写操作 三&#xff0c;创建Keil项目 四&#xff0c;代码 五&#xff0c;代码编译、下载到51单片机 六&a…

浏览器-服务器架构 (BS架构) 详解

目录 前言1. BS架构概述1.1 BS架构的定义1.2 BS架构的基本原理 2. BS架构的优势2.1 客户端简化2.2 易于更新和维护2.3 跨平台性强2.4 扩展性高 3. BS架构的劣势3.1 网络依赖性强3.2 安全性问题3.3 用户体验局限 4. BS架构的典型应用场景4.1 企业内部应用4.2 电子商务平台4.3 在…

洛谷 P10584 [蓝桥杯 2024 国 A] 数学题(整除分块+杜教筛)

题目 思路来源 登录 - Luogu Spilopelia 题解 参考了两篇洛谷题解&#xff0c;第一篇能得出这个式子&#xff0c;第二篇有比较严格的复杂度分析 结合去年蓝桥杯洛谷P9238&#xff0c;基本就能得出这题的正确做法 代码 #include<bits/stdc.h> #include<iostream&g…

单选题22届期末复习PTA

知识点&#xff1a; 1. (p->n) 会递增 p->n 的值&#xff0c;但是这个表达式的值仍然是递增之前的值 p->n 会得到 a[0].n 的值&#xff0c; p->n 也会递增 p->n 的值&#xff0c;但是这个表达式的值是递增后的值 p->next->n 访问 p 指向的结点的下一…