定义

     python中的闭包从表现形式上定义为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure),也就是说内层函数引用了外层函数的变量然后返回内层函数的情况就称之为闭包。
  闭包的特点是返回的函数还引用了外层函数的局部变量。所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变。

实例

# 希望返回六个函数,分别计算3*0,3*1,3*2,3*3,3*4,3*5
def operator():
return [lambda m: n * m for n in range(6)] print [o(3) for o in operator()]

上面的代码等同于:

# 希望返回六个函数,分别计算3*0,3*1,3*2,3*3,3*4,3*5
def operator():
fs = []
for n in range(6):
def func(m):
return m * n
fs.append(func)
return fs print [o(3) for o in operator()]

在内层函数func()中就用到了外层函数的局部变量n,但是n是变化的,本来我们希望输出的结果是[0, 3, 6, 9, 12, 15],但实际上输出的结果是[15, 15, 15, 15, 15, 15]。

        原因就是因为n是变化的,当operator()返回这六个函数时,这六个函数引用的n已经变成了5,由于这六个函数未被调用,所以未计算m×n,等到被调用时n已经变成了5,所以输出6个15。
        这个结果的出现,主要是因为Python中的迟绑定(late binding )机制,即闭包中变量的值只有在内部函数被调用时才会进行查询。因此,在上面的代码中,每次operator()所返回的函数被调用时,都会在附近的作用域中查询变量n的值(而到那时,循环已经结束,所以变量n最后被赋予的值为5)。
        那么该怎么修改代码使得结果符合我们的期望呢。

改进

# 希望返回六个函数,分别计算3*0,3*1,3*2,3*3,3*4,3*5
def operator():
return [lambda m, n=n: n * m for n in range(6)] print [o(3) for o in operator()]

或者是:

# 希望返回六个函数,分别计算3*0,3*1,3*2,3*3,3*4,3*5
def operator():
fs = []
for n in range(6):
def func(m, n=n):
return m * n
fs.append(func)
return fs print [o(3) for o in operator()]

输出:

[0, 3, 6, 9, 12, 15]  

Python闭包需要注意的问题的更多相关文章

  1. Python 闭包

    什么是闭包? 闭包(closure)是词法闭包(lexical closure)的简称.闭包不是新奇的概念,而是早在高级程序语言开始发展的年代就已产生. 对闭包的理解大致分为两类,将闭包视为函数或者是 ...

  2. Python闭包与函数对象

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

  3. Python闭包及装饰器

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

  4. Python闭包详解

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

  5. Python闭包及其作用域

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

  6. Python 闭包小记

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

  7. 理解Python闭包概念

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

  8. Python闭包举例

    Python闭包的条件: 1.函数嵌套.在外部函数内,定义内部函数. 2.参数传递.外部函数的局部变量,作为内部函数参数. 3.返回函数.外部函数的返回值,为内部函数. 举例如下: def line_ ...

  9. python 闭包和装饰器

    python 闭包和装饰器 一.闭包闭包:外部函数FunOut()里面包含一个内部函数FunIn(),并且外部函数返回内部函数的对象FunIn,内部函数存在对外部函数的变量的引用.那么这个内部函数Fu ...

  10. Python 闭包(Closure)

    Python  闭包 (Closure) 这里介绍一下python 的闭包 基本概念 闭包(closure)是函数式编程的重要的语法结构. 函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函 ...

随机推荐

  1. Apache Hive 建表操作的简单描述

    客户端连接hive [root@bigdata-02 bin]# ./beeline Beeline version by Apache Hive beeline: Connecting : Ente ...

  2. linux单用户模式修改密码

    Linux使用版本: Centos 7 救援模式: 1,在虚拟机设置里查看光驱是否开启启动,要保证设置状态里的两个选项都已选择. 2,先将Centos系统关机,然后在VMware左侧选中这台虚拟机并右 ...

  3. Solr4.3---4.6删除数据的办法

    Solr4.6的管理界面上,如果不配置数据导入的功能,将看不到清除数据的按钮.我表示很遗憾,正好我们线上没有配置数据导入的功能. 网上搜到的各种清理solr数据的HTTP请求,拿到我的solr4.6上 ...

  4. GCC笔记(警告.优化以及调试选项)

    GCC提供了大量的警告选项,对代码中可能存在的问题提出警告,通常可以使用-Wall来开启以下警告: -Waddress -Warray-bounds (only with -O2) -Wc++0x-c ...

  5. CSS文本溢出处理

    1.超出层的高度和宽度时文本自动隐藏 overflow:hidden;text-overflow:ellipsis; 2.超出层的宽度时隐藏溢出的文本以...表示,Firefox不兼容,只隐藏溢出的文 ...

  6. 微信WeixinJSBridge API 屏蔽右上角分享等常用方法

    WeixinJSBridge这个API有几个功能还是相当有用的,比如: 1.隐藏微信网页右上角的按钮(...按钮):开发者可以用这个功能来禁止当前页面被分享 2.隐藏微信网页底部的导航栏(比如前进后退 ...

  7. CF 961G Partitions

    推不动式子 我们考虑每一个$w_i$对答案的贡献,因为题目中定义集合的价值为$W(S) = \left | S \right |\sum_{x \in S}w_x$,这个系数$\left | S \r ...

  8. 2.Books

    Books示例说明了Qt中SQL类如何被Model/View框架使用,使用数据库中存储的信息,创建丰富的用户界面. 首先介绍使用SQL我们需要了解的类: 1.QSqlDatabase: QSqlDat ...

  9. Java学习——JSTL标签与EL表达式之间的微妙关系

    原文总结的太好了,忍不住记录.转发. 原文地址:http://blog.csdn.net/u010168160/article/details/49182867 目录(?)[-] 一EL表达式 EL相 ...

  10. 通过fork函数创建进程的跟踪,分析linux内核进程的创建

    作者:吴乐 山东师范大学 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.实验过程 1.打开gdb, ...