Python的三个问题

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

 def foo(a = []):
    a.append(1)
    print a

foo()foo()

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

def foo():
    a = 1 
    def bar():
        a += 1
        print a    return bar 

func = foo()func()

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

l = [x for x in xrange(10)]print x
d = {x : 2 * x for x in xrange(5)}print x

第一题的答案是

[1]

[1, 1]

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

第二题,运行会出现traceback。

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

LOAD_FAST aLOAD_CONST 1INPLACE_ADD

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

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

def foo():
    a = [1] 
    def bar():
        a[0] += 1
        print a[0]

    return bar 

func = foo()func()func()

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

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

原文发布于微信公众号 - HinusWeekly(gh_4b8b4eda4e40)

原文发表时间:2017-12-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据结构与算法

agc016D - XOR Replace(图论 智商)

不难看出,我们把所有数$xor$起来的数替换掉之后再次$xor$,得到的一定是被替换掉的数。

9850
来自专栏小灰灰

ForkJoin 学习使用笔记

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

323100
来自专栏C语言及其他语言

C语言逆向之表达式短路分析及应用

大家在学习C语言过程中,可能会见到过一些这样的题,就是表达式短路,表达式短路主要体现在C语言中逻辑运算符&&和||。今天将对表达式短路的做逆向分析,来深入理解它...

25740
来自专栏mathor

TRIE(4)

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

11240
来自专栏编程

Python的三个问题

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

18690
来自专栏瓜大三哥

HLS Lesson6-数据类型转换

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

465100
来自专栏desperate633

HashMap 与 HashTable的对比

而负载因子表示一个散列表的空间的使用程度,有这样一个公式:initailCapacity*loadFactor=HashMap的容量。

9620
来自专栏java架构师

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

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

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

洛谷P3812 【模板】线性基

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

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

27:除以13

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

32790

扫码关注云+社区

领取腾讯云代金券