首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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的这个问题。所以就会出现上面所说的问题了。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20171221G00PX300?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券