Python 2.7 闭包的局限
Python 2.7 的闭包中的自由变量(co_freevars)只读的.Python需要某些技巧来"变相修改"自由变量:
>>> def add(n):
freevar=[n]
def closure():
freevar[0]+=1
return freevar[0]
return closure >>> add100=add(100)
>>> add100()
101
>>> add100()
102
如果你这样定义,则会出错:
>>> def add(n):
def closure():
n+=1
return n
return closure >>> add100=add(100)
>>> add100() Traceback (most recent call last):
File "<pyshell#15>", line 1, in <module>
add100()
File "<pyshell#13>", line 3, in closure
n+=1
UnboundLocalError: local variable 'n' referenced before assignment
>>>
原因在于Python的数字,字符串是"不可变类型".列表是"可变类型".例如:
>>> a=10
>>> id(a)
19519444
>>> a=a+3
>>> id(a)
19519408
>>> a=[]
>>> id(a)
35054536
>>> a.append(1)
>>> id(a)
35054536
>>> a
[1]
>>>
而scheme的数字对象就是可变的,而且闭包中的自由变量是可以修改的:
> (define (add n)
(lambda () (set! n (+ 1 n)) n))
> (define add100 (add 100))
> (add100)
101
> (add100)
102
其实Python的n+=1有些类似于scheme的 (set! n (+ 1 n)).只不过Python中,n已经指向另外一个新对象了.而sheme,n指向的对象没有发生改变.
更多例证:
(define (add n)
(lambda () (set! n (+ 1 n)) n)) (define (addx n)
(lambda () (let ((n 200)) (set! n (+ 1 n)) n))) (define add5 (add 5))
(define addx5 (addx 5))
(add5)
(addx5)
(add5)
(addx5)
结果:
6
201
7
201
>
又如:
>>> def foo():
m = [3]
def bar(s):
s=m[0]+s
n=2
r=5
def eri():
print 2
for item in dir(bar.func_code):
if isinstance(getattr(bar.func_code,item),tuple):
print "%s : %s"%(item,getattr(bar.func_code,item)) >>> foo()
co_cellvars : ()
co_consts : (None, 0, 2, 5, <code object eri at 01ED8020, file "<pyshell#16>", line 7>)
co_freevars : ('m',)
co_names : ()
co_varnames : ('s', 'n', 'r', 'eri')
>>> def foo():
m = [3]
def bar(s):
s=m[0]+s
n=2
r=5
def eri():
print n
for item in dir(bar.func_code):
if isinstance(getattr(bar.func_code,item),tuple):
print "%s : %s"%(item,getattr(bar.func_code,item)) >>> foo()
co_cellvars : ('n',)
co_consts : (None, 0, 2, 5, <code object eri at 01FE3B18, file "<pyshell#19>", line 7>)
co_freevars : ('m',)
co_names : ()
co_varnames : ('s', 'r', 'eri')
>>>
co_varnames 本地变量
co_freevars 自由变量(闭包体现)
co_cellvars (被子函数引用的变量,不知叫啥合适)
Python 2.7 闭包的局限的更多相关文章
- 说说Python中的闭包 - Closure
转载自https://segmentfault.com/a/1190000007321972 Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西 ...
- 说说Python中的闭包
Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西. 闭包的概念 我们尝试从概念上去理解一下闭包. 在一些语言中,在函数中可以(嵌套)定义另一个 ...
- Python中的闭包 - Closure
Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西. 闭包的概念 我们尝试从概念上去理解一下闭包. 在一些语言中,在函数中可以(嵌套)定义另一个 ...
- 21.python中的闭包和装饰器
python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure). 以下说明主要针对 python ...
- 【转】python中的闭包
转自:http://www.cnblogs.com/ma6174/archive/2013/04/15/3022548.html python中的闭包 什么是闭包? 简单说,闭包就是根据不同的配置信息 ...
- Python 入门之 闭包
Python 入门之 闭包 1.闭包 (1)在嵌套函数内使用(非本层变量)和非全局变量就是闭包 (2)_ closure _ 判断是不是闭包 def func(): a = 1 def foo(): ...
- Python核心编程-闭包
百度搜了一下闭包的概念:简而言之,闭包的作用就是在外部函数执行完并返回后,闭包使得收机制不会收回函数所占用的资源,因为内部函数的执行需要依赖外函数中的变量.这是对闭包作用的非常直白的描述,不专业也不严 ...
- Python深入04 闭包
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 闭包(closure)是函数式编程的重要的语法结构.函数式编程是一种编程范式 (而 ...
- 轻松理解python中的闭包和装饰器 (下)
在 上篇 我们讲了python将函数做为返回值和闭包的概念,下面我们继续讲解函数做参数和装饰器,这个功能相当方便实用,可以极大地简化代码,就让我们go on吧! 能接受函数做参数的函数我们称之为高阶函 ...
随机推荐
- monogodb3.4安装修改,权限设置
下载地址:https://www.mongodb.com/download-center#community 这里的方法只对应3.4,别的有没有效果请自行判断. 下载后按默认下一步. 默认安装地址 ...
- C# 类型、存储和变量
如果广泛地描述C和C++程序的源代码的特征,可以说C程序是一组函数和数据类型,C++程序是一组函数和类,然而C#程序是一组类型声明. 既然C#程序就是一组类型声明,那么学习C#就是学习如何创建和使用类 ...
- STL迭代器------Traits编程技法详细理解(一)
最近在看STL源码解析的迭代器(iterators)一章,涉及到c++ Traits的编程技法,刚开始看时一头雾水,反复看了好几遍之后才理解这个东西,因此来写写在这方面的理解,如有错误,希望读者指正. ...
- Python求解啤酒问题(携程2016笔试题)
问题描述:一位酒商共有5桶葡萄酒和1桶啤酒,6个桶的容量分别为30升.32升.36升.38升.40升和62升,并且只卖整桶酒,不零卖.第一位顾客买走了2整桶葡萄酒,第二位顾客买走的葡萄酒是第一位顾客的 ...
- 物联网 MQTT 服务质量级别
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 翻译人:Tnecesoc,该成员来自云+社区翻译社 消息队列遥测传输(MQTT)是一种客户端服务器发布 / 订阅消息传输协议.它轻量,开放, ...
- 洛谷 P3038 [USACO11DEC]牧草种植Grass Planting(树链剖分)
题解:仍然是无脑树剖,要注意一下边权,然而这种没有初始边权的题目其实和点权也没什么区别了 代码如下: #include<cstdio> #include<vector> #in ...
- mysql列约束
列属性(约束)1: 是否允许为空(not null) --not null不允许为空create table t_1( a tinyint(3) zerofill not null, b ...
- [HNOI 2016]大数
Description 题库链接 给你一个长度为 \(n\) ,可含前导零的大数,以及一个质数 \(p\) . \(m\) 次询问,每次询问你一个大数的子区间 \([l,r]\) ,求出子区间中有多少 ...
- [Luogu 3768]简单的数学题
Description 输入一个整数n和一个整数p,你需要求出$(\sum_{i=1}^n\sum_{j=1}^n ijgcd(i,j))~mod~p$,其中gcd(a,b)表示a与b的最大公约数. ...
- ●BZOJ 2743 [HEOI2012]采花
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2743 题解: 树状数组,离线 求区间里面有多少种出现次数大于等于 2 的颜色. 类似某一个题 ...