python 延迟绑定
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 延迟绑定的更多相关文章
- Python函数——闭包延迟绑定
前言 请看下面代码 def multipliers(): return [lambda x : i*x for i in range(4)] print ([m(2) for m in multipl ...
- python闭包和延迟绑定
一.什么是闭包: 1.函数内定义函数. 2.外函数的返回时内函数的引用. 3.内函数使用外函数的局部变量(至少一个). 1 def outfunc(): 2 for num in range(4): ...
- PHP 面向对象编程和设计模式 (2/5) - 静态变量、属性和方法及延迟绑定
PHP高级程序设计 学习笔记 2014.06.10 Static(静态)关键字用来定义静态方法和属性,static 也可用于定义静态变量以及后期静态绑定. 1.静态变量 static variable ...
- Atitit 延迟绑定架构法attilax总结
Atitit 延迟绑定架构法attilax总结 配置文件的延迟绑定1 Api属性与方法的回调延迟绑定1 后期绑定和前期绑定2 延迟调用2 用 Java 语言延迟绑定2 什么是推迟绑定 C++3 配置文 ...
- PHP静态延迟绑定
静态延迟绑定的概念 PHP版本5.3起增加了静态延迟绑定,也称迟绑定,主要用于在继承范围内引用静态调用的类.简单地来说:static::不再被解析为当前方法所定义的类,而是在实际运行时计算的. // ...
- Scala学习之延迟绑定
package com.swust.example object TraitDemo2 extends App{ //抽象类 abstract class Writer { def writeMess ...
- PHP静态延迟绑定和普通静态效率简单对比
只是一个简单的小实验,对比了下 延迟绑定 和 非延迟的效率 延迟绑定主要就是使用 static 关键字来替代原来的 self ,但功能非常强大了 实验代码: class A { protected s ...
- ELF 文件 动态连接 - 延迟绑定(PLT)
PLT 全称:Procedure Linkage Table ,直译:过程连接表 由于在动态连接中,程序的模块之间包含了大量的函数引用,所以在程序开始执行前,动态链接会耗费较多的时间用于模块之间函数引 ...
- scala学习手记34 - trait方法的延迟绑定
trait的方法的延迟绑定就是先混入的trait的方法会后调用.这一点从上一节的实例中也可以看出来. 下面再来看一个类似的例子: abstract class Writer { def write(m ...
随机推荐
- 集合框架之——迭代器并发修改异常ConcurrentModificationException
问题: 我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现. 使用普通迭代器出现的异常: ...
- task9暂存
<h6>第一组项目</h6> <div class="wrap"> <div class="title"> &l ...
- 为什么重写equals时必须重写hashCode方法?
原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html 首先我们先来看下String类的源码:可以发现Stri ...
- oracle启动脚本 .
.#!/bin/bash set -x su -oracle >>EON lsnrctl start sqlplus /nolog >>EOF conn / as sy ...
- RPC学习--C#使用Thrift简介,C#客户端和Java服务端相互交互
本文主要介绍两部分内容: C#中使用Thrift简介 用Java创建一个服务端,用C#创建一个客户端通过thrift与其交互. 用纯C#实现Client和Server C#服务端,Java客户端 其中 ...
- Android布局中实现圆角边框
设置corners_bg.xml 设置边框圆角可以在drawable-mdpi目录里定义一个xml: <?xml version="1.0" encoding="u ...
- XE3随笔17:实例 - 模拟 Google 搜索
本例测试效果图: 代码文件: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics ...
- 浅析MVC模式与三层架构的区别01
三层架构和MVC是有明显区别的,MVC应该是展现模式(三个加起来以后才是三层架构中的UI层)三层架构(3-tier application) 通常意义上的三层架构就是将整个业务应用划分为:表现层(UI ...
- ubuntu安装jdk
首先,从http://java.sun.com或者http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archiv ...
- Crystal Reports拉报表报错:Error detected by database DLL
问题描述: 最近在使用Crystal Reports打印报表时,提示错误信息:"Error detected by database DLL." 如下图: 经查找,是因为数据库名称 ...