Python 进阶 (四) 浅谈 Python 闭包

浅谈Python闭包和late binding机制 从一个小问题开始 前几天在写代码的时候需要在循环中定义函数,却出现了预料之外的现象。先来看看下面这段简单的代码: def generate_funcs(): funcs = [] for i in range(5): funcs.append(lambda: print(i)) return funcs for f in generate_funcs(): f() 在循环过程中定... 阅读详情

一、前言

在函数内部定义的函数和外部定义的函数是一样的,只是他们无法被外部访问:

def g():    print 'g()...'def f():    print 'f()...'    return g

将 g 的定义移入函数 f 内部,防止其他代码调用 g:

def f():    print 'f()...'    def g():        print 'g()...'    return g

但是,考察定义的 calc_sum 函数:

def calc_sum(lst):    def lazy_sum():        return sum(lst)    return lazy_sum

注意: 发现没法把 lazy_sum 移到 calc_sum 的外部,因为它引用了 calc_sum 的参数 lst。

  • 像这种内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。

二、闭包函数

闭包特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。举例如下:

# 希望一次返回3个函数,分别计算1x1,2x2,3x3:def count():    fs = [ ]    for i in range(1, 4):        def f():             return i*i        fs.append(f)    return fsf1, f2, f3 = count()

你可能认为调用 f1(),f2()和 f3()结果应该是 1,4,9,但实际结果全部都是 9(请自己动手验证)。

原因就是当 count()函数返回了 3 个函数时,这 3 个函数所引用的变量 i 的值已经变成了 3。由于 f1、f2、f3 并没有被调用,所以,此时他们并未计算 i*i,当 f1 被调用时:

>>> f1()9     # 因为f1现在才计算i*i,但现在i的值已经变为3

因此,返回函数不要引用任何循环变量,或者后续会发生变化的变量。

返回闭包不能引用循环变量,请改写 count()函数,让它正确返回能计算 1x1、2x2、3x3 的函数。

考察下面的函数 f:

def f(j):    def g():        return j*j    return g

它可以正确地返回一个闭包 g,g 所引用的变量 j 不是循环变量,因此将正常执行。在 count 函数的循环内部,如果借助 f 函数,就可以避免引用循环变量 i。

参考代码:

def count():    fs = []    for i in range(1, 4):        def f(j):            def g():                return j*j            return g        r = f(i)        fs.append(r)    return fsf1, f2, f3 = count()print f1(), f2(), f3()

三、程序实例

 

理解Python闭包概念 其实问题的关键就在于在返回闭包列表fs之前for循环的变量的值已经发生改变了,而且这个改变会影响到所有引用它的内部定义的函数。运行的结果也说明了闭包函数中引用的父函数中local variable既不具有C++中的全局变量的性质也没有static变量的行为。函数my_func一旦返回,那么内部定义的函数func便是一个闭包,其中引用的变量j成为一个只和具体闭包相关的自由变量。应该怎么正确的理解呢?C++中有static关键字,函数中的static关键字定义的变量独立于函数之外,而且会保留函数中值的变化。 阅读详情

相关推荐

【python】Python中闭包的是什么,闭包原理分析与应用实战

在Python中,闭包(Closure)是一个非常重要的概念,它允许函数访问并操作其词法作用域之外的变量。闭包是由一个函数以及创建该函数时的作用域中变量的引用环境共同组成的。这个环境在闭包创建时确定,并且即便外部函数已经执行完毕,这个环境也不会被销毁。闭包在函数式编程、数据封装、装饰器等多个领域都有广泛的应用。

景天科技苑 2万+

Python进阶(四)浅谈Python闭包

注意: 发现没法把 lazy_sum 移到 calc_sum 的外部,因为它引用了 calc_sum 的参数 lst。像这种内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。

IT全栈 华强工作室 4万+

Stanford CS230深度学习(一)

斯坦福CS230可以作为深度学习的入门课,最近我也在跟着看视频、完成编程作业。首先列出使用的资源链接,然后给出第一课的理解和编程作业的代码。 所有资料如下: 一、课程连接: b站课堂讲授版:Stanford CS230(吴恩达 深度学习 Deep Learning | Autumn 2018)(中英双字幕) (一共10个视频,每周一个,但是每个视频对应下面的配套视频较多) Coursera配套视...

weixin_44750583的博客 2381

Python进阶(四)-浅谈Python闭包

分享一下我的偶像大神的人工智能教程!http://blog.youkuaiyun.com/jiangjunshow 也欢迎转载我的文章,转载请注明出处 https://blog.youkuaiyun.com/mm2zzyzzp Python进阶(四)-浅谈Python闭包   在函数内部定义的函数和外部定义的函数是一样的,只是他们无法被外部访问: def g(): ...

mm2zzyzzp的博客 186

FPGA时序分析中的工艺角:从PVT原理到建立保持时间验证

在数字电路设计中,静态时序分析(STA)是确保芯片功能正确和性能达标的核心验证手段。其基本原理是通过计算信号在逻辑路径上的传播延迟,检查建立时间和保持时间是否满足寄存器采样要求。这项技术的核心价值在于,它能在芯片制造前就预测并消除时序违规,极大提高设计成功率。然而,实际芯片性能会受到工艺波动、电压变化和温度漂移(合称PVT)的显著影响。为了覆盖这些不确定性,时序分析必须采用基于工艺角的边界模型——用最慢的工艺角模型验证建立时间,用最快的工艺角模型验证保持时间。这种分析方法广泛应用于FPGA和ASIC设计流程

weixin_30181209的博客 196

基于FMCW技术的毫米波雷达测速原理与应用

调频连续波(FMCW)技术是毫米波雷达中实现高精度测速的核心方法之一。本文详细介绍了FMCW测速的基本原理、信号处理流程以及在实际应用中的关键技术。通过分析FMCW雷达的多普勒效应和频率差测量方法,本文展示了如何利用FMCW技术实现目标速度的高精度检测。此外,本文还探讨了FMCW测速在自动驾驶、智能交通和工业自动化等领域的应用案例,为毫米波雷达开发者提供了理论支持和实践指导。

不谈枯燥公式,只聊雷达趋势。用大白话解读毫米波里的黑科技。 1137

[Python进阶]Python闭包的深入浅出

Python中的闭包并没有那么神秘,本文带你深入浅出的剖析python的闭包产生的原因,自由变量的使用,以及探究数据是怎样存储到这个’包’?。这个包指的是什么?

小鱼干儿的博客 3147

Golang面试(一)莉莉丝游戏-Golang后端开发-中台部门

莉莉丝游戏-Golang后端开发-中台部门 开场白,双方自我介绍,对方介绍这个岗位情况,erlang语言,全部转向go。 聊项目,介绍IM架构以及使用Go写的服务简介 动态扩容相关问题:平常30万,现在100万,你们现在是如何应对的? 如果让你调整架构实现动态扩容,你会怎么做?回答了kafka,是一种,应该还要使用docker和k8s以及微服务框架等 如果使用kafka,你是如何确保消息有序?回答了redis,好像没回答到那个点 消息发送失败的问题,如何做到消息不丢?回答持久化存储、拉消息和ACK 发送失

xmcy001122的专栏 3899

python中的闭包

谈谈对Python中闭包的理解 Python中的闭包是一个比较模糊的概念,有很多朋友都认为不好理解,但是随着深入学习,就会发现闭包无论如何都是需要去理解的,下面我将自己对闭包的理解进行阐述,希望能够对你有所帮助 ~ 闭包的理解 我们可以将闭包理解为一种特殊的函数,这种函数由两个函数的嵌套组成,且称之为外函数和内函数,外函数返回值是内函数的引用,此时就构成了闭包。 闭包的格式 下面用伪代码进行闭包格...

只小白的博客 3万+

别再为模糊的3D重建头疼了!手把手教你用3DSlicer处理DICOM数据,搞定医学影像三维可视化

本文详细解析了医学影像三维重建中常见的模糊问题,并手把手教你使用3DSlicer处理DICOM数据,实现精准的三维可视化。从层厚设置到数据格式转换,再到重建算法选择和渲染参数微调,提供了一套完整的优化方案,特别适合临床医生和医学影像处理人员提升工作效率。

weixin_28693447的博客 246

Apollo和autoware规划算法代码ros移植-路径规划可跑工程分享

Apollo6.0规划核心代码移植到Ros工程,可编译移植分享

weixin_39735688的博客 8508

Python中的闭包

(如转载,请注明出处,谢谢。) 闭包这个概念在很多语言中都有涉及,本文主要谈谈python中的闭包。Python中使用闭包主要是在进行函数式开发时使用。 一,定义 python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure).这个定义是相对直白的,好理解的,不像其他定义那样学究味道十

Marty_Fu的专栏 2万+

在MATLAB中将C语言代码转化为可执行的mexw64文件

这样,您可以将高效的C语言算法集成到MATLAB环境中,以便更好地利用MATLAB的功能和特性。请记住,在使用mex转换C语言代码之前,您需要正确编写和测试C语言代码,并确保它与MATLAB的mex接口兼容。MATLAB是一种功能强大的数值计算软件,它提供了一个机制,可以将C语言代码转化为MATLAB可执行的mexw64文件。在上述命令中,"-output"选项指定生成的mex文件的名称,"myfunction"是您选择的名称,"myfunction.c"是要编译的C语言源文件。步骤1:编写C语言代码。

CodeRoarX的博客 1427

python之闭包详解

闭包 1.什么是闭包 闭包的定义 自由变量 先检验一下自己的作用域基础:LEGB def outer(): a = 10 inner() def inner(): print(a) a = 20 outer() >>> 20 现在我们使用闭包来看一下 def outer(): a = 10 def inner(): print(a) return inner a = 20 outer()() >>> 1

weixin_45596210的博客 5076

第14.7章 高翔博士最新开源框架Lightning-LM源码解读(七):PoseExtrapolator模块深度剖析,揭秘激光SLAM高频位姿外推核心技术

PoseExtrapolator是Lightning-LM框架中负责高频位姿外推的核心模块,通过融合DR(航位推算)、激光里程计和PGO(位姿图优化)数据实现精准实时定位。模块初始化依赖PGO数据,后续通过DR数据进行高频位姿更新,并利用PGO结果进行误差补偿。关键函数AddDRLocAndExtrapolate处理DR增量位姿,结合速度补偿机制逐步修正误差,保证高频输出的同时提升精度。该模块体现了多传感器融合思想,通过互补性数据(高频DR与低频高精PGO)实现鲁棒定位,代码中使用了SE3位姿表示、互斥锁保

行知SLAM 348

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Python3之闭包浅谈

日期:2020年2月23日 作者:Commas 注释:学习就是为了忘记,接上一章《浅谈Python3函数命名空间与作用域》,现在讲一下Python闭包; 如果您想了解更多有关Python的知识,那么请点《我的Python浅谈系列目录》 文章目录一、闭包的形成二、闭包的示例 一、闭包的形成 闭包就是能够读取其他函数内部变量的内部函数,本质上就是函数,常见形式闭包的三要素: 存在一个嵌套函数...

Commas的博客 560

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Python进阶03-闭包和装饰器

为什么在全局作用域中无法访问局部变量?主要原因在于,在Python的底层存在一个“垃圾回收机制”,作用就是回收内存空间,加快计算机的运行。我们在Python代码中定义的变量也是需要占用内存的,所以Python为了回收已经被已经过的内存,会自动将函数运行以后的内部变量和程序直接回收。我们有没有办法把函数内部的局部变量保留?使用闭包,闭包定义:在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数的地址,我们把这个使用外部函数变量的内部函数称为闭包。

李宥的博客 1029

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

python 函数进阶(闭包,装饰器,递归)

装饰器被应用于函数时,会首先执行装饰器函数,并将目标函数作为参数传递给装饰器函数。装饰器函数返回一个新的函数(通常是一个内部定义的wrapper函数)来取代原始函数。

2201_75622573的博客 2331

Python进阶玩法#3:闭包

闭包相比对于函数来说,保存局部变量的功能是非常吸引人的。闭包不仅相对于Python中的类函数来说更加轻巧,并且也为装饰器的学习奠定坚实的基础!

2503_92038236的博客 841

【Python零基础到进阶】递归,闭包,匿名函数

【Python零基础到进阶】递归,闭包,匿名函数

2301_78096295的博客 1373

Python 进阶:闭包精讲——定义、语法、原理、实战全梳理

本文深入讲解Python闭包的核心概念与应用。闭包是一种特殊的嵌套函数,内部函数引用外部函数的局部变量,即使外部函数执行结束,内部函数仍能记住这些变量状态。文章详细解析闭包的三要素语法结构:函数嵌套、引用外部变量和返回内部函数对象,并强调nonlocal关键字在修改自由变量时的关键作用。通过货币转换器和温度控制器两个实战案例展示闭包的典型应用场景,帮助开发者掌握这一重要特性,写出更优雅、安全的代码。适合已掌握Python基础、想进阶学习函数高级特性的开发者阅读。

2501_93417686的博客 1749

python 函数进阶-闭包函数

闭包函数 什么是闭包函数 如果内函数使用了外函数的局部变量,并且外函数把内函数返回出来的过程叫做闭包,里面的内函数是闭包函数。 # 外函数 outer def outer(): # 外函数变量 num var = '外函数局部变量' # 内函数 inner def inner(): # 内函数使用了外函数的变量 num print('内函数使用了:' + var) # 外函数将使用了外函数的局部变量的内函数返回 return inner # 返回出的结果就是内函数 inner,现在

小可爱的博客 2360

Python 编程进阶之闭包

特别是装饰器,作为自动化测试人员一定不陌生,pytest测试框架就是利用装饰器的特性来实现特定的功能,比如通过@pytest.mark.parametrize装饰器能够实现数据驱动测试的功能,装饰器的本质其实就是闭包,所以在理解了闭包的基础上才能理解装饰器的原理,关于装饰器的使用可以关注后续的文章。

朱雀随云记的博客 801

python中闭包_浅谈python中的闭包

1. 函数引用先看下面的例子,理解函数引用:def test1():print("--- in test1 func----")# 调用函数test1()# 引用函数ret = test1print(id(ret))print(id(test1))#通过引用调用函数ret()运行结果:--- in test1 func----140212571149040140212571149040--- in...

weixin_39516865的博客 97

Python进阶————闭包与装饰器

python中的闭包与装饰器

记录学习笔记 1299
上一篇: Python 进阶 (三) 函数式编程之 reduce()
下一篇: Pytorch深度学习实战教程(一):开启炼丹模式,语义分割基础与环境搭建
wrr-cat
博客等级 码龄9年 128粉丝 302原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值