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吧! 能接受函数做参数的函数我们称之为高阶函 ...
随机推荐
- scrapy爬取中关村在线手机频道
# -*- coding: utf-8 -*- import scrapy from pyquery import PyQuery as pq from zolphone.items import Z ...
- SQL 语句 (二) --- SELECT
1 完整句法: SELECT [ ALL | DISTINCT TOP n [] WITH TIES select_list [INTO [new_table_name] ] [FROM {table ...
- 【SQL.基础构建-第二节(2/4)】
-- Tips:查询基础 --一.SELECT 语句基础-- 1.查询指定列:SELECT 关键字--语法:--SELECT <列名>, ... -- 希望查询列的名称- ...
- [LeetCode] Max Consecutive Ones II 最大连续1的个数之二
Given a binary array, find the maximum number of consecutive 1s in this array if you can flip at mos ...
- jdk 动态代理源码分析
闲来无事,撸撸源码 使用方法 直接看代码吧.. package com.test.demo.proxy; import java.lang.reflect.InvocationHandler; imp ...
- bzoj 4547 小奇的集合
Description 有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大 值.(数据保证这个值为非负数) Input 第一行有两个整数n ...
- HDU 1724 Ellipse
Problem Description Math is important!! Many students failed in 2+2’s mathematical test, so let's AC ...
- ●BZOJ 3551 [ONTAK2010]Peaks(在线)
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3551 题解: 最小生成树 Kruskal,主席树,在线 这个做法挺巧妙的...以Kruska ...
- [BZOJ]1045 糖果传递(HAOI2008)
放一道数学题. Description 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1. Input 第一行一个正整数n<=1000000,表示 ...
- HEOI2017游记
Day -1: noip与标准时限差了0.02秒,并没有申诉成功,导致NOIWC多交了900元钱. 滚回去准备学考,文科瞎写居然拿了A,可啪. NOIWC颓废记由于我实在太颓了所以懒得填坑了. THU ...