变量作用域

局部变量:在函数内部过程中定义的变量
全局变量:在函数外部模块中定义的变量
函数内部过程中,我们可以直接引用全局变量,但是对全局变量进行引用修改时,修改的是创建的一个副本,并不会修改原全局变量。
而通常,我们无法对函数内部的局部变量进行引用,因为一旦运行完毕,局部变量就会被python的回收机制清除。
闭包,就是一种保存函数内部局部变量的方式。

闭包 Closure

首先看一下维基百科的解释:
在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。
(1)这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。
(2)所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。
(3)闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。
我们将这三句话标注出来,通过例子进行理解

闭包示例

以下示例中,外函数均用 out_func 表示,内函数(闭包)均用 in_func 表示
例1:

def out_func():msg = 'hello'def in_func():print(msg)return in_func
a = out_func()
a() #输出结果:hello

在外函数中,将字符串hello赋值给局部变量msg,内函数中则引用该变量并print。
a=out_func()表示:将闭包 in_func 实例化给变量a。此时使用a()时,我们并没有再调用外函数 out_func ,但是仍然引用了out_func的局部变量变量msg。
此时,根据标注【1】的维基百科解释,此时的msg称为自由变量,在out_func运行结束后,并没有被python的垃圾回收机制回收,仍可以被内函数in_func调用,并且该变量将与函数一同存在
例2:

def out_func(msg):def in_func():print(msg)return in_func
a = out_func('hello')
a() #输出结果:hello

在例2中,我们将字符串hello作为参数,传递给外函数out_func,并将内函数in_func实例化给a。此时,调用a()的结果为我们传递给外函数的变量hello。
此时,无论调用多少次a(),运行的结果都相当于print(‘hello’),即引用了外函数变量的内函数。这个定义,与标注【2】的解释符合:闭包是由内函数in_func与内函数引用环境(msg)组合而成的实体(实例a)
例3:

def out_func(a,b):def in_func(x):return a*x+breturn in_func
y1 = out_func(3,2)   #y = 3 * x + 2
y2 = out_func(4,5)   #y = 4 * x + 5
print(y1(5) )#输出结果:17
print(y2(5) )#输出结果:25

在该示例中,我们进行了两次参数不同的实例化,然后向两个实例化对象中传入相同的参数5。得到的结果却不同。
a的含义相当于一元一次函数 y = 3 * x + 2
b的含义相当于一元一次函数 y = 4 * x + 5
所以,我们只需要在实例化时,传入不同的参数,即可生成不同的实例。而这一特点,正好与标注【3】的解释相符合:闭包在运行时可以有多个实例,不同的引用环境(a,b)和相同的函数 in_func 组合可以产生不同的实例(y1,y2)

闭包能干什么?

通过三个示例和维基百科的解释相互验证,我们初步了解了闭包是个什么东西。但是闭包这么复杂,到底能做什么呢?
我们以生成4个二元一次函数为例:
常规写法:

def y1(a,b):y = 2 * a + breturn y
def y2(a,b):y = 3 * a + 2 * breturn y
def y3(a,b):y = 4 * a + 3 * breturn y
def y4(a,b):y = 5 * a + 4 * breturn y
a = 2
b = 3
print(y1(a,b)) #输出结果为:7
print(y2(a,b)) #输出结果为:12
print(y3(a,b)) #输出结果为:17
print(y4(a,b)) #输出结果为:22

闭包写法:

def out_func(a,b):def in_func(x , y):return a * x + b * yreturn in_func
y1 = out_func(2,1)
y2 = out_func(3,2)
y3 = out_func(4,3)
y4 = out_func(5,4)
x = 2
y = 3
print(y1(x,y)) #输出结果:7
print(y2(x,y)) #输出结果:12
print(y3(x,y)) #输出结果:17
print(y4(x,y)) #输出结果:22

通过对照两种写法,我们可以很明显看出差距。如果用常规写法,一个函数就要定义一次。如果要生成2x+1y、3x+2y、4x+3y、5x+4y、6x+5y……等这一系列有规律的函数十个,若使用常规方法,光是定义都要写几十行,而通过闭包的写法,只需要定义一次函数,实例化十次即可搞定。
下面再举一个例子
例4:

def out_func(x6=0,x5=0,x4=0,x3=0,x2=0,x1=0,b=0):def in_func(x):y = x6*x**6+x5*x**5+x4*x**4+x3*x**3+x2*x**2+x1*x**1+breturn yreturn in_func
a = out_func(x6=1,x1=1,b=1)
print(a(2)) #输出结果:67

此闭包通过传递参数,实例化生成的是一元六次函数。此处实例化的一元六次函数为y = x**6 + x + 1 ,若要生成一元一次,一元二次,一元三次乃至一元六次函数,通过闭包的写法,只需要向指定参数传入系数即可即可。
通过简单的示例,可以看出,闭包结构的存在,可以大大简化代码大的数量。如在需要批量创建结构类似的函数时,使用闭包写法比常规写法要方便很多。而这一特点和类有异曲同工之妙,都是面向对象的屠龙宝刀。闭包在python中还一个用途,称为装饰器。关于装饰器的用法,之后再写一篇吧

python 闭包及个人理解相关推荐

  1. 深入理解Python闭包概念

    闭包并不只是一个Python中的概念,在函数式编程语言中应用较为广泛.理解python中的闭包一方面是能够正确的使用闭包,另一方面可以好好体会和思考闭包的设计思想. 1.概念介绍 首先看一下维基上对闭 ...

  2. python 闭包理解与应用

    一.概念介绍 闭包并不只是一个python中的概念,在函数式编程语言中应用较为广泛.理解python中的闭包一方面是能够正确的使用闭包,另一方面可以好好体会和思考闭包的设计思想. 首先看一下维基上对闭 ...

  3. Python 闭包详解

    在函数编程中经常用到闭包.闭包是什么,它是怎么产生的及用来解决什么问题呢.给出字面的定义先:闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)(想想Erlang的外层函数传入一个 ...

  4. Python闭包与延迟绑定

    Python闭包 1.什么是闭包,闭包必须满足以下3个条件: 必须有一个内嵌函数 内嵌函数必须应用外部函数的变量 外部函数的返回值必须是内嵌函数 举个栗子 # 嵌套函数但不是闭包 def nested ...

  5. Python闭包与装饰器

    Python闭包与装饰器 一.闭包       函数是一个对象,所以可以对象的形式作为某个函数的结果返回.函数执行完后内部变量将会被回收.在闭包中,由于内部函数存在对外部函数的变量的引用,所以即使外部 ...

  6. python闭包的应用场景_简单谈谈Python中的闭包

    Python中的闭包 前几天又有人留言,关于其中一个闭包和re.sub的使用不太清楚.我在脚本之家搜索了下,发现没有写过闭包相关的东西,所以决定总结一下,完善Python的内容. 1. 闭包的概念 首 ...

  7. python闭包的应用场景_Python闭包函数定义与用法分析

    python函数的闭包怎么理解小编憎恨离别.但若,离别能让你牵挂,小编愿意离开你. 1. 闭包的概念 首先还得从基本概念说起,什么是闭包呢?来看下维基上的解释: 复制代码代码如下: 在计算机科学中,闭 ...

  8. Python闭包基本介绍与作用

    目录 1.闭包基本介绍 1.1 外函数的返回值是内函数的引用 1.2 外函数把临时变量绑定给内函数 1.3 闭包中内函数修改外函数局部变量 2.闭包的作用 1.闭包基本介绍 "闭包" ...

  9. [转载] 根据Python常见面试题来谈谈 Python 闭包

    参考链接: Python闭包 这里根据我们平常见到的一些Python常见面试题来跟大家说一下关于Python闭包的相关问题! 题目: 1.什么是闭包?闭包的定义? 2.手写一个简单的闭包 3.变量作用 ...

最新文章

  1. 前端最新技术学习地址总结
  2. 关于带资源部门的一些总结
  3. 【ESP8266】ESP8266_NONOS_SDK开发包生成的镜像文件构建步骤分析
  4. C#隐藏任务栏区图标(非右下角托盘)
  5. 牛顿-拉夫逊法 原理讲解以及python算例实现
  6. 在EXCEL中如何将一列中的相同值的数据行找出来?
  7. netcore docker_让.NetCore程序跑在任何有docker的地方
  8. 《C语言接口与实现:创建可重用软件的技术》一1.5 习题
  9. 严蔚敏算法约瑟夫环_极客算法训练笔记(三),链表详细图解,别再逃避了朋友...
  10. python abc模块_3-2 抽象基类abc模块
  11. 物联网火爆,开发者却遇到这个大难题!
  12. 实验吧——Recursive
  13. 跑马灯java代码_[Java教程]JQ跑马灯
  14. Visual C++ 2010 Express 下载及安装教程
  15. Noi2001 食物链(入门oj Problem 1706)
  16. 地产行业主数据建设项目思考
  17. AIR小应用--北京机动车限行提示
  18. 逆元 阶乘逆元 数论 HDU 5651 xiaoxin juju needs help
  19. [EKL-踩坑记] —— ES虚拟内存设置
  20. 从兴电子笔试题目小结

热门文章

  1. k8s集群reset恢复重置
  2. 有点厉害!用12万行代码堆出来个蔡徐坤,编译还能通过!
  3. 视频聊天网站的研究、发展以及趋势(转)
  4. C# 操作现有Word表格详细教程
  5. iOS:UITableView实现飘带动画
  6. SQ01报表添加事物码
  7. 我们离成为C++、C#、MySQL之父有多远?
  8. c语言程序设计作业03
  9. iOS10、11自定义左滑菜单项背景图片
  10. PHP Warning: file_put_contents(..):failed to open stream: Permission denied in...