一段关于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 ...
随机推荐
- codevs1993 草地排水(最大流)
1993 草地排水 USACO 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在农夫约翰的农场上,每逢下雨,Bes ...
- Entity Framework 4.3 中使用存储过程
尽管 Entity Framework 4.3 都已经发布了,且表示在 EF 5 中性能将会有很大提升.但很多存储过程控,始终不会放弃使用存储过程,那今天就让我们看看在 EF 4.3 中怎么使用存储过 ...
- C# 工厂单例
public class BusinessFactory { private static BusinessFactory instance = null; pri ...
- $P1596 [USACO10OCT]湖计数Lake Counting$
\(problem\) 其实这题吧\(DFS\)好写一点(大雾 所以就不讲\(DFS\)了 em \(BFS\)的话 主要是 判重. 方向. 队列.(没了吧 至于位置 用两个队列?还是\(pair\) ...
- PHP入门开发
1.下载开发工具phpstorm 地址:http://www.jetbrains.com/phpstorm/download/download-thanks.html?platform=windows ...
- 1、Web MVC简介
- xampp中localhost与DreamWaver站点设置问题
作为一个初学者,在DreamWaver中配置web服务器用于本地测试,中间碰到了好多问题,百度答案模糊不清,自己摸索出来,把自己碰到的,易错的地方做个总结. step1 : 安装xampp(安装位置记 ...
- Android开发高手课 - 02 崩溃优化(下):应用崩溃了,你应该如何去分析?
崩溃现场 1. 崩溃信息 进程名.线程名 崩溃类型和堆栈信息 2. 系统信息 Logcat 机型.系统.厂商.CPU.ABI.Linux 版本等 设备状态:是否 root.是否模拟器.是否有 Xpos ...
- DOS批处理命令-字符串操作
1.字符串替换 语法结构:%变量名:替换前=替换后% @set str=teh cat in teh hat @echo %str% @set str=%str:teh=the% @echo %str ...
- Centos6.7 编译安装 Apache PHP
Centos6.7 编译安装 Apache PHP 原文地址:http://www.cnblogs.com/caoguo/p/4968039.html ##### Apache 编译安装 #### [ ...