Python的三个问题

第一,以下程序的执行结果是什么?

deffoo(a=[]):a.append(1)printafoo()foo()

第二,以下程序的执行结果是什么?

deffoo():a=1defbar():a+=1printareturnbar func=foo()func()

第三,以下程序的执行结果是什么?

l=[xforxinxrange(10)]printxd={x:2*xforxinxrange(5)}printx

第一题的答案是

[1]

[1, 1]

这是因为,在Python中,Function是一种Object,所以foo函数其实是一个FunctionObject,它的默认参数是与这个Object绑定在一起的。所以,每次调用,所使用的参数a其实是同一个list对象。

第二题,运行会出现traceback。

出现这个的原因是因为Python编译器写得太简单了。它并没有合理地处理所有变量的scope。我们希望产生一个闭包,在bar方法里可以看得到它外面的变量。但是,实际上,我们得到的Python字节码是这样的:

LOAD_FAST a

LOAD_CONST 1

INPLACE_ADD

问题就出在这个LOAD_FAST上,我们知道,正确的闭包所使用的字节码其实应该是LOAD_CLOSURE。但在这里,因为在bar方法里,对a进行了赋值,所以编译器就把a当做了局部变量。访问一个未定义的局部变量当然就是错的了。

要想在Python里使用闭包,正确的做法是:

deffoo():a=[1]defbar():a[]+=1printa[]returnbar func=foo()func()func()

第三题,在2.7里,可以正确运行。结果是9, 9。

在2.6的时代,只支持列表推导式,字典推导式还没有得到支持。所以,如果你在2.6上运行这段程序,是会报错的。其实,在2.6的列表推导式的实现中,有一个设计缺陷,那就是循环变量x会污染外层的命名空间。也就是说,我执行完列表推导式以后,x 会进到程序的locals表里。而在2.7里,在实现字典表达式的时候,却又把这个循环变量做为局部变量处理了。所以离开了推导式,这个x就消失不见了。同时,2.7没有修复2.6的这个问题。所以就会出现上面所说的问题了。

本文来自企鹅号 - 全球大搜罗媒体

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏mathor

TRIE(4)

 这道题的大意是我们有一个网站,然后要配置规则,决定哪些IP能访问,哪些IP不能。这些规则大概长这个样子:

11140
来自专栏数据结构与算法

洛谷P3812 【模板】线性基

1 \leq n \leq 50, 0 \leq S_i \leq 2 ^ {50}1≤n≤50,0≤Si​≤250

7420
来自专栏海纳周报

Python的三个问题

第一,以下程序的执行结果是什么? def foo(a = []): a.append(1) print a foo()foo() 第二,以下...

29570
来自专栏java架构师

【SQL Server】系统学习之三:逻辑查询处理阶段-六段式

一、From阶段 针对连接说明: 1、笛卡尔积 2、on筛选器 插播:unknown=not unknuwn 缺失的值; 筛选器(on where having...

368110
来自专栏Objective-C

Swift 基本语法03-"if let"和"guard let"

43940
来自专栏偏前端工程师的驿站

PLT:说说Evaluation strategy

Brief                                 在学习方法/函数时,我们总会接触到 按值传值 和 引用传值 两个概念。像C#是按值传...

21660
来自专栏数据结构与算法

27:除以13

27:除以13 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB描述 输入一个大于0的大整数N,长度不超过100位,要求输出其除...

32490
来自专栏禅林阆苑

LESS 学习demo 【原创】

LESS 学习demo Write By CS逍遥剑仙 我的主页: www.csxiaoyao.com GitHub: github.com/...

41090
来自专栏瓜大三哥

HLS Lesson6-数据类型转换

1.整数数据类型 传统的C语言可以采用:数据类型 数据变量 赋值 int var = -1; ap_int<6> a_6bit_var_c = -22;//复制...

449100
来自专栏小灰灰

ForkJoin 学习使用笔记

ForkJoin 学习使用笔记 Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结...

321100

扫码关注云+社区

领取腾讯云代金券