>>> 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 闭包的例子的更多相关文章

  1. python闭包小例子

    ------------------ 首先根据实例, 体会一下闭包的效果 ------------------ 定义闭包: def foo(x): a = [0] def bar(y): a[0] = ...

  2. Python闭包详解

    Python闭包详解 1 快速预览 以下是一段简单的闭包代码示例: def foo(): m=3 n=5 def bar(): a=4 return m+n+a return bar >> ...

  3. Python 闭包小记

    闭包就是能够读取其他函数内部变量的函数.例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“.在本质上,闭包是将函数内部和函数外部连接起来 ...

  4. 理解Python闭包概念

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

  5. 高逼格利器之Python闭包与装饰器

    生活在魔都的小明,终于攒够了首付,在魔都郊区买了一套房子:有一天,小明踩了狗屎,中了一注彩票,得到了20w,小明很是欢喜,于是想干脆用这20万来装修房子吧(decoration): 整个装修过程,小明 ...

  6. Python闭包与函数对象

    1. Python闭包是什么 在python中有函数闭包的概念,这个概念是什么意思呢,查看Wikipedia的说明如下: “ In programming languages, closures (a ...

  7. Python闭包及装饰器

    Python闭包 先看一个例子: def outer(x): def inner(y): return x+y return innder add = outer(8) print add(6) 我们 ...

  8. Python闭包及其作用域

    Python闭包及其作用域 关于Python作用域的知识在python作用域有相应的笔记,这个笔记是关于Python闭包及其作用域的详细的笔记 如果在一个内部函数里,对一个外部作用域(但不是全局作用域 ...

  9. Python闭包的高级应用-装饰器的实现

    我们先看一个闭包的例子: from time import ctime def before_call(f): def wrapped(*args, **kargs): print 'before c ...

随机推荐

  1. Entity Framework 4.3 中使用存储过程

    尽管 Entity Framework 4.3 都已经发布了,且表示在 EF 5 中性能将会有很大提升.但很多存储过程控,始终不会放弃使用存储过程,那今天就让我们看看在 EF 4.3 中怎么使用存储过 ...

  2. JavaScript--改变 HTML 样式

    HTML DOM 允许 JavaScript 改变 HTML 元素的样式.如何改变 HTML 元素的样式呢? 语法: Object.style.property=new style; 注意:Objec ...

  3. Croppic插件使用介绍-asp.net

    具体的参数使用和基本使用方式请看:http://www.uedsc.com/croppic-api.html 需要说明的几点: 1.支持两种上传方式: (1)先将原图上传至服务器,然后再次将切图信息传 ...

  4. V-SQL的简单使用

    V-SQL概述: V-SQL,是对同望V3平台时间多数据支持非常重要的基础引擎.因为各个数据库的查询语句的语法有所不同,V-SQL的功能是把查询语句解析为执行系统连接的数据库(MSSQL,Oracle ...

  5. SQL--大解密之组织数据

    今天为大家带来的是数据库的基本用法   首先带大家了解下数据库. 大量的数据正在不断产生,伴随而来的是如何安全有效地存储.检索.管理他们. 对数据的有效存储.高效访问.方便共享和安全控制等问题成为信息 ...

  6. iOS- Size Class使用教程

    1:它引入了一种新的概念,抛弃传统意义上我们适配时所谓的具体宽高尺寸,把屏幕的宽和高分别分成两种情况:Compact-紧凑, Regular-正常(Any-任意,其实就是这2种的组合,所以我没分成3种 ...

  7. (转)在 vue-cli 脚手架中引用 jQuery、bootstrap 以及使用 sass、less 编写 css [vue-cli配置入门]

    写在前面: 本文是vue-手摸手教你使用vue-cli脚手架-详细步骤图文解析之后,又一篇关于vue-cli脚手架配置相关的文章,因为有些文章步骤不够清晰,当时我引入JQuery.bootstrap的 ...

  8. js技巧(二)

    1.封装获取id: function show(Id){ var aa=document.getElementById(Id); return aa; } 调用:console.log(show(&q ...

  9. 本地运行项目成功 ,但在服务器运行程序就会报Failed to establish a new connection: [Errno -2] Name or service not known

    equests.exceptions.ConnectionError: HTTPSConnectionPool(host=): Max retries exceeded with url: /appa ...

  10. 一个数据去重sql

    参考: https://www.jb51.net/article/129656.htm DELETE testcaseFROM testcase,  (  SELECT  max(id) id,  a ...