def multipliers(n):

  funcs = []

  for i in range(n):

    def f(x):

      return x * i

    funcs.append(f)

  return funcs

g0, g1, g2, g3 = mutipliters(4)

print(g0(10))                 # 30

print(g1(10))                 # 30

print(g1(10))                 # 30

print(g1(10))                 # 30

被同学问道如上问题, 为什么,生成的4个函数.最终返回的值一样.

查看了四个函数的内存地址,是不同的内存地址.

说明四个函数,是不同的函数.不是因为函数明重复,导致了覆盖的问题

那就是说明 i 值的问题.

打印出四个函数调用时,i 的值,发现都是3,

但是, 没有循环发生,所以是直接访问了i的值

于是查看了 四个函数掉用时, i 的id, id(i)的值相同. 发现是同一个内存地址.

也就是说函数调用的时候,是动态取 i 所在地址里面的值, 而在生成函数range结束的时候,i 的值 已经不变了.所以出现了以上问题.

查询了一些结论,最终如下结论:

python里, 非局部变量绑定的是空间, 而不是值本身,所以,生成的函数i, 相对于函数f 来说, 是全局变量, 所以绑定的是 i 所在的内存地址.

所以导致了,生成的四个函数所得值时相同的.

那么如何实现呢? 将 i 变成局部变量, 变成i 的一个参数, 并赋予一个默认值,这样, 函数f绑定的就是值, 而不是内存地址:

def multipliers(n):

  funcs = []

  for i in range(n):

    def f(x, m=i):  #每次生成函数, i的值, 都被绑定到函数本身

      return x * m

    funcs.append(f)

  return funcs

g0, g1, g2, g3 = mutipliters(4)

print(g0(10))                 # 0

print(g1(10))                 # 10

print(g1(10))                 # 20

print(g1(10))                 # 30

有兴趣的可以查询一下  python 延迟绑定和闭包的问题~

ps: 为什么将 x 换成 *arg, 出现如下情况???

def multipliers(n):

  funcs = []

  for i in range(n):

    def f(*arg):  #每次生成函数, i的值, 都被绑定到函数本身

      return arg * i

    funcs.append(f)

  return funcs

g0, g1, g2, g3 = mutipliters(4)

print(g0(10))          #  (10, 10, 10)

目前不明白~欢迎赐教

python 延迟绑定的更多相关文章

  1. Python函数——闭包延迟绑定

    前言 请看下面代码 def multipliers(): return [lambda x : i*x for i in range(4)] print ([m(2) for m in multipl ...

  2. python闭包和延迟绑定

    一.什么是闭包: 1.函数内定义函数. 2.外函数的返回时内函数的引用. 3.内函数使用外函数的局部变量(至少一个). 1 def outfunc(): 2 for num in range(4): ...

  3. PHP 面向对象编程和设计模式 (2/5) - 静态变量、属性和方法及延迟绑定

    PHP高级程序设计 学习笔记 2014.06.10 Static(静态)关键字用来定义静态方法和属性,static 也可用于定义静态变量以及后期静态绑定. 1.静态变量 static variable ...

  4. Atitit 延迟绑定架构法attilax总结

    Atitit 延迟绑定架构法attilax总结 配置文件的延迟绑定1 Api属性与方法的回调延迟绑定1 后期绑定和前期绑定2 延迟调用2 用 Java 语言延迟绑定2 什么是推迟绑定 C++3 配置文 ...

  5. PHP静态延迟绑定

    静态延迟绑定的概念 PHP版本5.3起增加了静态延迟绑定,也称迟绑定,主要用于在继承范围内引用静态调用的类.简单地来说:static::不再被解析为当前方法所定义的类,而是在实际运行时计算的. // ...

  6. Scala学习之延迟绑定

    package com.swust.example object TraitDemo2 extends App{ //抽象类 abstract class Writer { def writeMess ...

  7. PHP静态延迟绑定和普通静态效率简单对比

    只是一个简单的小实验,对比了下 延迟绑定 和 非延迟的效率 延迟绑定主要就是使用 static 关键字来替代原来的 self ,但功能非常强大了 实验代码: class A { protected s ...

  8. ELF 文件 动态连接 - 延迟绑定(PLT)

    PLT 全称:Procedure Linkage Table ,直译:过程连接表 由于在动态连接中,程序的模块之间包含了大量的函数引用,所以在程序开始执行前,动态链接会耗费较多的时间用于模块之间函数引 ...

  9. scala学习手记34 - trait方法的延迟绑定

    trait的方法的延迟绑定就是先混入的trait的方法会后调用.这一点从上一节的实例中也可以看出来. 下面再来看一个类似的例子: abstract class Writer { def write(m ...

随机推荐

  1. 【POJ3691】DNA repair(AC自动机,DP)

    题意: 生物课上我们学到,DNA序列中只有A, C, T和G四种片段. 经科学发现,DNA序列中,包含某些片段会产生不好的基因,如片段"ATC"是不好片段,则"AGATC ...

  2. 如何将红色区域数据调用解密函数直接打印到输出控制台(例如:crt控制台)

    int main(int argc, char *argv[]) { unsigned char data[PACKET_MAX_LEN]; int data_len = 0; int socket_ ...

  3. Oracle:ORA-00955: name is already used by an existing object

    下午从生产库导出了一份表结构,用来测试一些问题,由于生产库连接着其他用户下的表所以通过视图在本地模拟一下,于是创建视图: create or replace view csews as select ...

  4. 运行开源项目,报错Error:(48, 37) 错误: -source 1.6 中不支持 diamond 运算符,请使用-source 7或者更高版本已启用diamond运算符

    错误定位 当时并没有弄明白为什么会出错,一脸懵逼相 解决办法: 将source compatibility和target compatibility都改为1.7,重新build就ok了. 错误原因: ...

  5. Mac 终端命令大全

    目录操作 命令名 功能描述 使用举例 mkdir 创建一个目录 mkdir dirname rmdir 删除一个目录 rmdir dirname mvdir 移动或重命名一个目录 mvdir dir1 ...

  6. Java Calendar 注意事项

    Java JDK 提供了java.util.Calendar来处理日期和时间.Calendar是一个抽象类,是所有日历的模板,因此我们可以继承Calendar来实现其他的历法(比如阴历). Java提 ...

  7. Flash Builder 调试器无法连接到正在运行的应用程序(57%)

    Flash Builder 调试器无法连接到正在运行的应用程序(57%),可能原因:     1,flashplayer不是debug版.     2,调试器(用debug版flashplayer随便 ...

  8. 在ubuntu16编译安装nginx-1.10.2(full)完全自带组件

    第一步:先安装全部用到的包 apt install gcc libpcre++-dev libssl-dev make \ libxml2-dev libxslt-dev libgd-dev libg ...

  9. oracle win7下 卸载

    1 右击“计算机”-->管理-->服务和应用程序-->服务,停掉所有Oracle相关的服务(以Oracle打头的,比如OracleDBConsoleorcl). 2 开始--> ...

  10. POJ 3057 Evacuation 二分图匹配

    每个门每个时间只能出一个人,那就把每个门拆成多个,对应每个时间. 不断增加时间,然后增广,直到最大匹配. //#pragma comment(linker, "/STACK:10240000 ...