python的闭包与延时绑定问题
起源于一道面试题...
def mul():
return [lambda x : i*x for i in range(4)] print([m(2) for m in mul()]) # output:
# [6, 6, 6, 6]
为什么答案是[6,6,6,6]而不是[0,2,4,6]呢?
为了便于理解,把代码改写成下面的样子
def mul():
func_list = []
for i in range(4):
def lam(x):
return x*i
func_list.append(lam)
return func_list print([m(2) for m in mul()])
怎么理解呢?简单来说,在python里,相对而言的局部变量绑定的是值,非局部变量绑定的是空间, 而不是值本身,所以,for循环生成的i,相对于函数lam来说,是全局变量,所以绑定的是i所在的内存地址,但i最后变成了3,lam绑定的是3。
所以导致了,生成的四个函数所得值时相同的.
那么如何实现结果为 [0, 2, 4, 6] 呢? 按照刚才的思路,我们只需将lam函数中的 i 变成局部变量,这样函数lam绑定的就是值, 而不是内存地址:
def mul():
func_list = []
for i in range(4):
def lam(x,i=i):
return x*i
func_list.append(lam)
return func_list print([m(2) for m in mul()])
这里i是局部变量,所以绑定的是i的值
python的闭包与延时绑定问题的更多相关文章
- python中闭包详解
谈谈自己的理解:python中闭包,闭包的实质 闭包这个概念好难理解,身边朋友们好多都稀里糊涂的,稀里糊涂的林老冷希望写下这篇文章能够对稀里糊涂的伙伴们有一些帮助~ 请大家跟我理解一下,如果在一个 ...
- Python的闭包
Python的闭包 闭包概念都是一样的,实现机制一样,看看下面的代码是不是和javascript很像 def generate_counter(): cnt = [0] def count_one() ...
- Python之闭包
Python之闭包 我们知道,在装饰器中,可以在函数体内创建另外一个函数,例如: def makebold(fn): def wrapped(): return "<b>&quo ...
- JavaScript闭包和this绑定
本文最主要讲讲JavaScript闭包和this绑定相关的我的小发现,鉴于这方面的基础知识已经有很多很好的文章讲过了,所以基本的就不讲了,推荐看看[酷壳](http://coolshell.cn/)上 ...
- Python函数编程——闭包和装饰器
Python函数编程--闭包和装饰器 一.闭包 关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数).而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数.当其中一个 ...
- 前端(十三)—— JavaScript高级:回调函数、闭包、循环绑定、面向对象、定时器
回调函数.闭包.循环绑定.面向对象.定时器 一.函数高级 1.函数回调 // 回调函数 function callback(data) {} // 逻辑函数 function func(callbac ...
- python闭包和延迟绑定
一.什么是闭包: 1.函数内定义函数. 2.外函数的返回时内函数的引用. 3.内函数使用外函数的局部变量(至少一个). 1 def outfunc(): 2 for num in range(4): ...
- Python函数——闭包延迟绑定
前言 请看下面代码 def multipliers(): return [lambda x : i*x for i in range(4)] print ([m(2) for m in multipl ...
- 【Python】 闭包&装饰器
python中的函数本身就是对象,所以可以作为参数拿来传递.同时其允许函数的层级嵌套定义,使得灵活性大大增加. 闭包 闭包的定义:将函数的语句块与其运行所需要的环境打包到一起,得到的就是闭包对象.比如 ...
随机推荐
- 深入理解Spring AOP之二代理对象生成
深入理解Spring AOP之二代理对象生成 spring代理对象 上一篇博客中讲到了Spring的一些基本概念和初步讲了实现方法,当中提到了动态代理技术,包含JDK动态代理技术和Cglib动态代理 ...
- 剑指offer-复杂链表的复制
题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否 ...
- Hive为什么要启用Metastore?
转载来自: https://blog.csdn.net/qq_40990732/article/details/80914873 https://blog.csdn.net/tp15868352616 ...
- python中列表中元素的增删改查
增: append : 默认添加到列表的最后一个位置 insert : 可以通过下标添加到列表的任意位置 extend: a.extend[b] --将b列表的元素全加入到列表b中 删; remove ...
- 关于Oracle 10.2.0.5 版本应用SCN补丁14121009相关问题
环境:OEL 5.7 + Oracle 10.2.0.5 背景:Oracle发布的两篇关于2019年6月份将自动调整高版本数据库的SCN COMPATIBILITY的MOS文章引起了很多客户的恐慌,尤 ...
- Cisco Packet Tracer
---恢复内容开始--- 1.简单局域网组建 交换机:2960 s1 终端设备:generic pc 配置 pc1 单击>>Descktop>>IP configur ...
- day05 Python中的set集合
集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的.以下是集合最重要的两点: 1.去重,把一个列表变成集合,就自动去重了. 2.关 ...
- C# AsyncCallback异步回调用法示例
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- JavaWeb-----ServletConfig对象和servletContext对象
1.ServletConfig ServletConfig:代表当前Servlet在web.xml中的配置信息 String getServletName() -- 获取当前Servlet在web. ...
- Java 五大原则
1.单一职责 不论是在设计类,接口还是方法,单一职责都会处处体现,单一职责的定义:我们把职责定义为系统变化的原因.所有在定义类,接口,方法的时候.定义完以后再去想一想是不能多于一个的动机去改变这个类, ...