一段关于python 闭包的例子
>>> def counter(a=0):
... count = a
... def incr():
... b = 1 + count
... return b
... return incr
...
>>> count = counter(5)
>>> print count()
6
>>> print count()
6
>>>
>>> def counter(start_at=0):
... count = [start_at]
... def incr():
... count[0] += 1
... return count[0]
... return incr
...
>>> count = counter(5)
>>> print count()
6
>>> print count()
7
>>> print count()
8
>>>
有若干疑点不懂。 列出来一一解惑
1. 第二段代码的function counter 在内部定义了一个function incr。这个incr被当做返回值返回。 我们用count 去接受这个返回值然后每次调用的时候 print count() 会得到累加的结果6, 7 , 8. 但是这个累加值的变量应该是定义在counter()这个外层函数中的啊。 以我的理解外层函数结束了,其定义的变量应该也不可访问了。为什么count函数可以不断的访问并累加这个值呢?
这是因为python中对变量的访问都是引用。外层函数生成了一个变量,内层函数count又对这个变量引用了一次。只要内层函数对这个变量的引用还在,这个变量就不会被销毁,就仍然可用。 我所理解的外层函数退出,变量就不可以再访问其实是因为我潜意识里认为外层函数退出,变量的引用就结束了。然而在这个例子中变量的引用并没有结束,所以仍然存在并且可以访问。
2. 对于第二段代码,我们知道它返回一个函数调用。那么也就是说counter()类似于一个函数名。而我们用counter()()就应该是这个函数调用。 我们看一下执行,
>>> counter()()
1
>>> counter()()
1
确实是函数调用,但是为什么不是像print count()这种累加呢?
这是因为,counter()每次运行生成一个新的函数对象并返回。如下所示:
>>> counter()
<function incr at 0xe10c848>
>>> counter()
<function incr at 0xe10ca28>
>>>
所以 counter()()每次都相当于第一次执行。每次是在执行不同的函数instance。 而 count=counter() print count()这种方式则不然。 这种方式是执行一次counter()以后把返回的函数调用保存在一个变量也就是count中形成了一次引用。以后每次调用print count()都是对这同一个函数调用。
一段关于python 闭包的例子的更多相关文章
- python闭包小例子
------------------ 首先根据实例, 体会一下闭包的效果 ------------------ 定义闭包: def foo(x): a = [0] def bar(y): a[0] = ...
- Python闭包详解
Python闭包详解 1 快速预览 以下是一段简单的闭包代码示例: def foo(): m=3 n=5 def bar(): a=4 return m+n+a return bar >> ...
- Python 闭包小记
闭包就是能够读取其他函数内部变量的函数.例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“.在本质上,闭包是将函数内部和函数外部连接起来 ...
- 理解Python闭包概念
闭包并不只是一个python中的概念,在函数式编程语言中应用较为广泛.理解python中的闭包一方面是能够正确的使用闭包,另一方面可以好好体会和思考闭包的设计思想. 1.概念介绍 首先看一下维基上对闭 ...
- 高逼格利器之Python闭包与装饰器
生活在魔都的小明,终于攒够了首付,在魔都郊区买了一套房子:有一天,小明踩了狗屎,中了一注彩票,得到了20w,小明很是欢喜,于是想干脆用这20万来装修房子吧(decoration): 整个装修过程,小明 ...
- 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闭包及其作用域 关于Python作用域的知识在python作用域有相应的笔记,这个笔记是关于Python闭包及其作用域的详细的笔记 如果在一个内部函数里,对一个外部作用域(但不是全局作用域 ...
- Python闭包的高级应用-装饰器的实现
我们先看一个闭包的例子: from time import ctime def before_call(f): def wrapped(*args, **kargs): print 'before c ...
随机推荐
- BZOJ 3779 LCT 线段树 DFS序 坑
hhhh抄了半天lty代码最后T了 对拍也没事.. 药丸 mine #pragma GCC optimize("O3") //By SiriusRen #include < ...
- Codeforces 803G Periodic RMQ Problem ST表+动态开节点线段树
思路: (我也不知道这是不是正解) ST表预处理出来原数列的两点之间的min 再搞一个动态开节点线段树 节点记录ans 和标记 lazy=-1 当前节点的ans可用 lazy=0 没被覆盖过 els ...
- URI、URL、请求、响应、常见状态代码
URI:路径(统一资源标识符,包括本地地址和网络地址) URL是URI的一种子路径, URI范围比URL范围广. URL (Uniform Resource Locator,统一全球资源定位符): 通 ...
- 363 Max Sum of Rectangle No Larger Than K 最大矩阵和不超过K
Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix s ...
- Python随笔-字符串
函数title.lower.upper. ct = "hello WORLD" print(ct.title()) #title 以首字母大写的方式显示每个单词 print(ct. ...
- N的阶乘末尾有多少个零?
在创联ifLab的招新问答卷上看到这么一题 核心问题是: 求N!(N的阶乘)的末尾有多少个零? 由于在N特别大的时候强行算出N!是不可能的,所以肯定要另找方法解决了. 首先,为什么末尾会有0?因为2* ...
- mysql常用命令介绍
mysql适用于在Internet上存取数据,支持多种平台 1.主键:唯一标识表中每行的这个列,没有主键更新或删除表中的特定行很困难. 2.连接mysql可以用Navicat 要读取数据库中的内容先要 ...
- HDU_1087_Super Jumping! Jumping! Jumping!_dp
Super Jumping! Jumping! Jumping! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 ...
- Address space layout randomization
Address space layout randomization (ASLR) is a computer security technique involved in preventing ex ...
- Redis 之order set有序集合结构及命令详解
1.zadd key score1 value1 score2 value2 添加元素 2.zrem key value1 value2 .. 删除集合中的元素 3.zremrangebyscor ...