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. ubuntu apt 安装

    1. ./autogen.sh: libtoolize: not found sudo apt-get install aptitude sudo aptitude install libtool 2 ...

  2. Android笔记:DrawerLayout抽屉布局的使用

    DrawerLayout(抽屉布局),在各种app中经常出现,比如csdn.. 如下示,只要从屏幕侧边滑一下,或者点击左上角的图标,抽屉就会出来. DrawerLayout要点: 1.使用Drawer ...

  3. js自定义对象

    一,概述 在Java语言中,我们可以定义自己的类,并根据这些类创建对象来使用,在Javascript中,我们也可以定义自己的类,例如定义User类.Hashtable类等等. 目前在Javascrip ...

  4. Android学习---如何创建数据库,SQLite(onCreate,onUpgrade方法)和SQLiteStudio的使用

    一.android中使用什么数据库? SQLite是遵守ACID的关系数据库管理系统,它包含在一个相对小的C程式庫中.它是D.RichardHipp建立的公有领域项目.SQLite 是一个软件库,实现 ...

  5. asp.net 将word文档进行编辑并导出一个新的word

    最近做项目,需要多word文档进行编辑并导出一个新的word,在最初的word编辑中留下特定的字符串用来替换,然后在本地生成一个新的word文档,并且不修改服务器中的word文档,这样才能保证服务器中 ...

  6. 自定义View(二)增加View的属性

    增加View的属性有两种方法    1.在View类中添加    2.在xml资源文件中添加 一.在View类中添加    例:实现一个带文字的图片 public class MyView exten ...

  7. mssql

    1.打开php.ini,将 ;extension=php_mssql.dll前面的分号(;)去掉,然后重启 Apache. 如果不行的话,进行第2步: 2.检查一下你的php安装目录下的ext下面有没 ...

  8. .NET 4.0 中超长路径超长文件名的问题

    1. 昨天开发中遇到一个问题,场景如下: 客户端从服务器下载一个文件并解压,客户端在使用后需要做清理操作(删除解压出来的文件),结果删除失败,抛出如下异常: The specified path, f ...

  9. easyui datagrid 加载两次请求,触发两次ajax 请求 问题

    datagrid初始化的时候请求两次URL 两种情况 1. <table id="gridview" class="easyui-datagrid"> ...

  10. 一 java线程的等待/通知模型

    java 中线程之间的通信问题,有这么一个模型:一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作,整个过程开始于一个线程,而最终执行又是另一个线程.前者是生产者,后者就是消费者 ...