Python:闭包
闭包(Closure)
在一个函数内部定义另一个函数,然后内部函数用到外部函数的变量,把内部函数以及用到的外部变量,合称闭包。
首先复习一下
命名空间与作用域
我们可以把命名空间看做一个大型的字典类型(Dict),里面包含了所有变量的名字和值的映射关系。在 Python 中,作用域实际上可以看做是“在当前上下文的位置,获取命名空间变量的规则”。在 Python 代码执行的任意位置,都至少存在三层嵌套的作用域:
- local 最内层作用域,最早搜索,包含所有局部变量**(Python 默认所有变量声明均为局部变量)**
- non-local 所有包含当前上下文的外层函数的作用域,由内而外依次搜索,这里包含的是非局部也非全局的变量
- global 一直向上搜索,直到当前模块的全局变量
- built-in 最外层,最后搜索的,内置(built-in)变量
在任意执行位置,可以将作用域看成是对下面这样一个命名空间的搜索:
scopes = |
除了默认的局部变量声明方式,Python 还有global和nonlocal两种类型的声明(nonlocal是Python 3.x之后才有,2.7没有),其中 global 指定的变量直接指向(3)当前模块的全局变量,而nonlocal则指向(2)最内层之外,global以内的变量。这里需要强调指向(references and assignments)的原因是,普通的局部变量对最内层局部作用域之外只有**只读(read-only)**的访问权限,比如下面的例子:
>>>x = 100 #该全局变量可被所有函数调用
>>def main():
x += 1
print(x) >>>main()
Traceback (most recent call last):
File "<pyshell#50>", line 1, in <module>
main()
File "<pyshell#49>", line 2, in main
x += 1
UnboundLocalError: local variable 'x' referenced before assignment
这里抛出UnboundLocalError,是因为main()函数内部的作用域对于全局变量x仅有只读权限,想要在main()中对x进行改变,不会影响全局变量,而是会创建一个新的局部变量,显然无法对还未创建的局部变量直接使用x += 1。如果想要获得全局变量的完全引用,则需要global声明:
>>>x = 100
>>>def main():
global x
x += 1
print(x) >>>main()
print(x) # 全局变量已被改变,后面的全局变量x都为101
101
Python闭包
demo:
# 外部函数
def fun():
print('outer')
# 内部函数
def fun_in():
print('inner')
return fun_in # 调用外部函数
fun()
a = fun()
print(a)
# 调用内部函数
a() # 输出结果
outer
<function fun.<locals>.fun_in at
inner
再写个闭包调用时机的小例子
def fun():
print('---1---')
def fun_in():
print('---2---')
print('---3---')
return fun_in # 注意没有小括号 # fun()
# 输出结果
# ---1---
# ---3--- # 调用 fun_in才输出---2---
a = fun()
print('-------')
a() #输出结果
---1---
---3---
-------
---2---
闭包在内存中的状态
在python函数的使用里,当函数调用结束后,函数对应的内存空间被释放,里面所有东西都被清空
但在闭包中例外,因为函数里面还有东西(内部函数)被引用了。因此外部函数的空间就没被释放(涉及到python回收机制的知识:引用计数)
如果再次调用这个函数,就还会重新生成一份新的内存空间
def fun(number):
def fun_in(number_in):
print('number = %d, number_in = %d' % (number, number_in))
return number + number_in
return fun_in a1 = fun(3)
print(a1(8)) # 11 = 3 + 8 a2 = fun(5)
print(a2(8)) # 13 = 5 + 8 print(a1(9)) # 12 = 3 + 9 print(a2(9)) # 14 = 5 + 9

所以,当通过a1去调用内部函数,和通过a2去调用内部函数的时候,实际上是在不同的内存空间上去跑的。
Python:闭包的更多相关文章
- Python 闭包
什么是闭包? 闭包(closure)是词法闭包(lexical closure)的简称.闭包不是新奇的概念,而是早在高级程序语言开始发展的年代就已产生. 对闭包的理解大致分为两类,将闭包视为函数或者是 ...
- Python闭包与函数对象
1. Python闭包是什么 在python中有函数闭包的概念,这个概念是什么意思呢,查看Wikipedia的说明如下: “ In programming languages, closures (a ...
- Python闭包及装饰器
Python闭包 先看一个例子: def outer(x): def inner(y): return x+y return innder add = outer(8) print add(6) 我们 ...
- Python闭包详解
Python闭包详解 1 快速预览 以下是一段简单的闭包代码示例: def foo(): m=3 n=5 def bar(): a=4 return m+n+a return bar >> ...
- Python闭包及其作用域
Python闭包及其作用域 关于Python作用域的知识在python作用域有相应的笔记,这个笔记是关于Python闭包及其作用域的详细的笔记 如果在一个内部函数里,对一个外部作用域(但不是全局作用域 ...
- Python 闭包小记
闭包就是能够读取其他函数内部变量的函数.例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“.在本质上,闭包是将函数内部和函数外部连接起来 ...
- 理解Python闭包概念
闭包并不只是一个python中的概念,在函数式编程语言中应用较为广泛.理解python中的闭包一方面是能够正确的使用闭包,另一方面可以好好体会和思考闭包的设计思想. 1.概念介绍 首先看一下维基上对闭 ...
- Python闭包举例
Python闭包的条件: 1.函数嵌套.在外部函数内,定义内部函数. 2.参数传递.外部函数的局部变量,作为内部函数参数. 3.返回函数.外部函数的返回值,为内部函数. 举例如下: def line_ ...
- python 闭包和装饰器
python 闭包和装饰器 一.闭包闭包:外部函数FunOut()里面包含一个内部函数FunIn(),并且外部函数返回内部函数的对象FunIn,内部函数存在对外部函数的变量的引用.那么这个内部函数Fu ...
- Python 闭包(Closure)
Python 闭包 (Closure) 这里介绍一下python 的闭包 基本概念 闭包(closure)是函数式编程的重要的语法结构. 函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函 ...
随机推荐
- Python对象(下)
前面一篇文章介绍了一些Python对象的基本概念,这篇接着来看看Python对象相关的一些内容. Python对象的比较 Python对象有三个要素:身份,类型和值,所以我们就分别从这三个角度出发看看 ...
- vuejs监听苹果iphone手机键盘事件
在iphone手机中,vue提供的keyup事件是不能监听iphone键盘的,但是h5提供的input事件可以做到. 只需要向下面这样处理,就可以解决iphone不响应键盘事件的bug <tem ...
- OpenGL资料
苹果官方文档:OpenGL ES for iOS苹果官方文档:OpenGL for OS X OpenGL是源自SGI IRIS GL library,并不是SUN开发的.SGI提供了一个OPENGL ...
- Create maintenance backup plan in SQL Server 2008 R2 using the wizard
You will need to identify how you want your maintenance plan to be setup. In this example the mainte ...
- RAC的搭建(一)--安装环境准备
软硬件环境准备: 1.1 虚拟环境: VirtualBox上两个虚拟机,3G内存1核 1.2 软件环境: 数据库安装软件:p10404530_112030_LINUX_1of7.zip p10404 ...
- <转>pandas学习
1.Pandas 基本介绍 Numpy 和 Pandas 有什么不同? 如果用 python 的列表和字典来作比较, 那么可以说 Numpy 是列表形式的,没有数值标签,而 Pandas 就是字典形式 ...
- numpy常用举例
转自https://morvanzhou.github.io/tutorials/data-manipulation/np-pd/2-1-np-attributes/ numpy 的属性: ndim: ...
- Window 命令行神器:cmder
http://cmder.net/ https://github.com/cmderdev/cmder/releases/ 官网下载地址 http://www.360doc.com/content ...
- guzzle http异步 post
use GuzzleHttp\Pool;use GuzzleHttp\Client;//use GuzzleHttp\Psr7\Request;use Psr\Http\Message\Respons ...
- JavaScript arguments对象详解
1. 什么是 arguments MDN 上解释: arguments 是一个类数组对象.代表传给一个function的参数列表. 我们先用一个例子直观了解下 JavaScript 中的 argume ...