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

  1. 说说Python中的闭包 - Closure

    转载自https://segmentfault.com/a/1190000007321972 Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西 ...

  2. 说说Python中的闭包

    Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西. 闭包的概念 我们尝试从概念上去理解一下闭包. 在一些语言中,在函数中可以(嵌套)定义另一个 ...

  3. Python中的闭包 - Closure

    Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西. 闭包的概念 我们尝试从概念上去理解一下闭包. 在一些语言中,在函数中可以(嵌套)定义另一个 ...

  4. 21.python中的闭包和装饰器

    python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure). 以下说明主要针对 python ...

  5. 【转】python中的闭包

    转自:http://www.cnblogs.com/ma6174/archive/2013/04/15/3022548.html python中的闭包 什么是闭包? 简单说,闭包就是根据不同的配置信息 ...

  6. Python 入门之 闭包

    Python 入门之 闭包 1.闭包 (1)在嵌套函数内使用(非本层变量)和非全局变量就是闭包 (2)_ closure _ 判断是不是闭包 def func(): a = 1 def foo(): ...

  7. Python核心编程-闭包

    百度搜了一下闭包的概念:简而言之,闭包的作用就是在外部函数执行完并返回后,闭包使得收机制不会收回函数所占用的资源,因为内部函数的执行需要依赖外函数中的变量.这是对闭包作用的非常直白的描述,不专业也不严 ...

  8. Python深入04 闭包

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 闭包(closure)是函数式编程的重要的语法结构.函数式编程是一种编程范式 (而 ...

  9. 轻松理解python中的闭包和装饰器 (下)

    在 上篇 我们讲了python将函数做为返回值和闭包的概念,下面我们继续讲解函数做参数和装饰器,这个功能相当方便实用,可以极大地简化代码,就让我们go on吧! 能接受函数做参数的函数我们称之为高阶函 ...

随机推荐

  1. 追女神助手v0.1

    #-*-coding:utf8-*- import smtplib from email.mime.text import MIMEText import requests from lxml imp ...

  2. scrapy 选择器官方文档

    当抓取网页时,常见的任务是从HTML源码中提取数据.现有的一些库可以达到这个目的: BeautifulSoup lxml Scrapy 提取数据有自己的一套机制.它们被称作选择器(seletors), ...

  3. 字符串分割方法split()函数

    >>> data = '1000,小甲鱼,男'>>> data.split(',')['1000', '小甲鱼', '男'] str.split('以什么为标志进行 ...

  4. cookielib和urllib2模块结合模拟网站登录

    1.cookielib模块 cookielib模块的主要作用就是提供可存储cookie的对象,以便于与urllib2模块配合使用来访问internet资源,例如可以利用本模块的cookiejar类的对 ...

  5. Linux云服务器安装Elasticsearch

    安装Elasticsearch 注:本人服务器为CentOS7.3镜像 1.下载JDK 在安装JDK之前需要检查是否已存在其他版本JDK. 采用如下命令可查看当前已存在JDK版本: java -ver ...

  6. 031718-js变量、数据类型、运算符

    1.关键字.标识符.变量(是一个名称,最好用字母开头,对大小写敏感).常量 (是有数据类型的一个值) 变量: ①定义并赋值 ②使用   2.数据类型:数字  字符串  布尔  null  undefi ...

  7. JS实现手机访问pc网址自动跳转到wap网站

    之前写pc端直接跳转wap端一直是后端java写的,跟js一样都是根据navigator.userAgent来判断设备是电脑还是手机的,我知道这种前端也可已完成的功能,只是后台比较强势,本人本着以和为 ...

  8. Docker And Swarm Mode(一)

    (一)节点的创建和配置 前言  虽然工作中一直在用Docker和Docker Swarm,但是总感觉有点陌生,总想自己亲手来写写和配置Docker 容器相关的事情,这篇文章主要是参考了Los Tech ...

  9. 【模板】KMP字符串匹配

    题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next. (如果你不知道这是什么意思也不要问,去百度 ...

  10. [HNOI2009]有趣的数列

    题目描述 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所有的奇数项满足a1<a3<...<a2n ...