千家信息网

Python闭包怎么实现

发表于:2025-02-04 作者:千家信息网编辑
千家信息网最后更新 2025年02月04日,本篇内容介绍了"Python闭包怎么实现"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、闭包的概念
千家信息网最后更新 2025年02月04日Python闭包怎么实现

本篇内容介绍了"Python闭包怎么实现"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1、闭包的概念

请大家跟我理解一下,如果在一个函数的内部定义了另一个函数,外部的我们叫他外函数,内部的我们叫他内函数。闭包: 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。

2、实现一个闭包

# 将函数作为返回值返回,也是一种高阶函数# 这种高阶函数我们也称为叫做闭包,通过闭包可以创建一些只有当前函数能访问的变量#   可以将一些私有的数据藏到的闭包中def outer():    a = 10    # 函数内部再定义一个函数    def inner():        print('我是outer', a)    # 将内部函数 inner作为返回值返回    return inner# r是一个函数对象,是调用fn()后返回的函数对象# 这个函数实在fn()内部定义,并不是全局函数# 所以这个函数总是能访问到fn()函数内的变量# 外函数返回了内函数的引用fn = outer()# r()相当于调用了inner()函数print("outer引用地址:", outer)print("inner引用地址:", fn)fn()"""输出结果:outer引用地址: inner引用地址: .inner at 0x0000000002BB58B8>我是outer 10"""

说明上述代码:

对于闭包,在外函数outer中 最后return inner,我们在调用外函数 fn = outer() 的时候,outer函数返回了inner函数对象,inner函数对象是一个函数的引用,这个引用被存入了fn对象中。所以接下来我们再进行fn() 的时候,相当于运行了inner函数。

提示:

一个函数,如果函数名后紧跟一对括号,相当于调用这个函数。如果不跟括号,相当于只是一个函数的名字,里面存了函数所在位置的引用。

3、在闭包中外函数把临时变量绑定给内函数

按照我们正常的认知,一个函数结束的时候,会把自己的临时变量都释放还给内存,之后变量都不存在了。一般情况下,确实是这样的。但是闭包是一个特别的情况。外部函数发现,自己的临时变量会在将来的内部函数中用到,自己在结束的时候,返回内函数的同时,会把外函数的临时变量送给内函数绑定在一起。所以外函数已经结束了,调用内函数的时候仍然能够使用外函数的临时变量。

在我编写的实例中,我两次调用外部函数outer,分别传入的值是10和20。内部函数只定义了一次,我们发现调用的时候,内部函数是能识别外函数的临时变量是不一样的。

Python中一切都是对象,虽然函数我们只定义了一次,但是外函数在运行的时候,实际上是按照里面代码执行的,外函数里创建了一个函数,我们每次调用外函数,它都创建一个内函数,虽然代码一样,但是却创建了不同的对象,并且把每次传入的临时变量数值绑定给内函数,再把内函数引用返回。

所以我们每次调用外函数,都返回不同的实例对象的引用,他们的功能是一样的,但是它们实际上不是同一个函数对象。

下面示例进行演示:

def outer(num):    a = num    # 函数内部再定义一个函数    def inner():        print('我是outer', a)    # 将内部函数 inner作为返回值返回    return innerfn1 = outer(10)fn2 = outer(20)print("inner引用地址:", fn1)fn1()print("inner引用地址:", fn2)fn2()"""输出结果:inner引用地址: .inner at 0x00000000026B58B8>我是outer 10inner引用地址: .inner at 0x00000000026B5828>我是outer 20"""# 注意两个inner的地址不一样,一个是8B8,一个是828。

4、闭包中内函数修改外函数局部变量

在基本的Python语法当中,一个函数可以随意读取全局数据,但是要修改全局数据的时候有两种方法

global声明全局变量。全局变量是可变类型数据的时候可以修改。

在闭包内函数也是类似的情况。在内函数中想修改闭包变量(外函数绑定给内函数的局部变量)的时候,在Python3中,可以用nonlocal关键字声明一个变量, 表示这个变量不是局部变量空间的变量,需要向上一层变量空间找这个变量。

示例:

def outer(num):    a = num    b = 10  # a和b都是闭包变量    print("原始a值为", a)    # inner内函数    def inner():        # 内函数中想修改闭包变量        # nonlocal关键字声明变量        nonlocal a        a += b        print('我是outer的a', a)    # 将内部函数 inner作为返回值返回    return innerfn1 = outer(10)fn1()"""输出结果:原始a值为 10我是outer的a 20"""

在内函数中,对闭包变量进行了修改,打印出来的结果也确实是修改之后的结果。

5、注意:

还有一点需要注意,闭包变量实际上只有一份,每次调用一份闭包变量。(这个在Python实现的单利模式下来解释更多)

def outer(num):    a = num    b = 10  # a和b都是闭包变量    print("原始a值为", a)    # inner内函数    def inner():        # 内函数中想修改闭包变量        # nonlocal关键字声明变量        nonlocal a        a += b        print('我是outer的a', a)    # 将内部函数 inner作为返回值返回    return innerfn1 = outer(10)fn1()fn1()fn1()"""输出结果:原始a值为 10我是outer的a 20我是outer的a 30我是outer的a 40"""

可以看到第二次第二次调用fn1()方法,a的值有增加了10。

6、练习:

# 求多个数的平均值# nums = [50,30,20,10,77]# sum()是一个求和函数# sum()用来求一个列表中所有元素的和# print(sum(nums)/len(nums))# 结果:37.4# 形成闭包的要件#   ① 函数嵌套#   ② 将内部函数作为返回值返回#   ③ 内部函数必须要使用到外部函数的变量def make_averager():    # 创建一个列表,用来保存数值    nums = []    # 创建一个函数,用来计算平均值    def averager(n) :        # 将n添加到列表中        nums.append(n)        # 求平均值        return sum(nums)/len(nums)    return averager# 创建对象,现在就是获得了内函数对象的引用averager = make_averager()# 调用内涵书对象# 这里注意,虽然是调用外函数创建的对象,# 但是获得的是内函数对象的引用,内函数是有形参的,# 所以averager对象相当于是内函数对象。# 所以调用内函数就要传递形参。print(averager(10))print(averager(20))print(averager(30))print(averager(40))

"Python闭包怎么实现"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

函数 变量 闭包 对象 时候 地址 结果 情况 全局 输出 原始 实际 局部 数据 代码 关键 关键字 实际上 平均值 更多 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 宜兴专注软件开发报价 传奇游戏服务器租用 网络安全生态时代的课题 ntp校时服务器地址 学软件开发在那里 网络安全第二季度工作 华宇软件网络安全 两个数据库比对小程序 邮件服务器部署 四川工控软件开发定制费用 db2数据库怎么查表名和表描述 通信技术与信息网络技术区别 华为手机无法连接服务器怎么开启 陪聊软件开发模式 软件开发游戏制作 本地数据库启动后 普陀区正规数据库系统是真的吗 软件开发销售退税 水电厂网络安全防护系统 吉安高性价比服务器找哪家公司 数据库加密数据怎么查 共享股东分红系统软件开发 辅警违反网络安全法被罚款 英雄联盟各个地区服务器英雄选择 幼儿园沉迷网络安全教育反思 佳都科技软件开发有限公司 南海网络安全设备 江阴智能软件开发诚信经营 甘肃应急频道家庭教育与网络安全 部队网赌网贷网络安全教育
0