一个Python语法问题求解惑

2014-01-13 10:40:32 +08:00
 jayn1985
def outer():
x = 1
y = 0

def inner():
print locals() #1
z = x +1
print locals()

return inner

outer()()

我的疑惑主要在#1处,为啥这时输出为{'x': 1},而不是{}呢?(python版本为2.7)
3994 次点击
所在节点    Python
12 条回复
njustyw
2014-01-13 10:49:29 +08:00
这个是闭包的问题吧
woshifyz
2014-01-13 10:51:04 +08:00
因为python奇怪的lexical scope,当内部函数中只读同名变量时,它就是外部变量;但当你写同名变量时,它就是局部变量。python3 中添加nonlocal来解决这一问题

你把 z=x+1 这行换成 x=10 就知道了
jayn1985
2014-01-13 10:55:27 +08:00
@njustyw 能详细说说么?inner函数通过作用域链使用outer函数的变量x,这个我了解,但是和locals方法结合起来看,有点糊涂了,一直没弄明白#1的结果是如何生成的
yeelone
2014-01-13 10:57:31 +08:00
这个属于闭包的概念,x 此时属于自由变量
jayn1985
2014-01-13 10:59:45 +08:00
@woshifyz 你说的这个我理解,我困惑的主要是在#1这行语句执行之前,并没有对变量x的读操作啊,为啥locals还能输出x呢?或者这个说,为啥y没有输出来但是却输出x了呢?
woshifyz
2014-01-13 11:06:30 +08:00
@jayn1985 先有编译,后有执行
winfred
2014-01-13 11:17:14 +08:00
Update and return a dictionary representing the current local symbol table. Free variables are returned by locals() when it is called in function blocks, but not in class blocks.

按官方文档,locals()也输出被调用的自由变量。
jayn1985
2014-01-13 13:36:11 +08:00
@woshifyz 感谢指点,这个跟js的预编译是一样的概念么?如果预编译可以得知变量x,为啥变量z却没有输出呢?还是有些糊涂。。。
yuelang85
2014-01-13 14:06:34 +08:00
能用gist排下版吗?完全不明白楼主意图
woshifyz
2014-01-13 14:09:44 +08:00
@jayn1985 因为那个时候变量z还没有定义,而python在编译成opcode的时候就已经知道x是只读的,所以在inner中可以引用outer中的x,你可以理解为inner默认有一个const x=1,关于此,你可以看看lua中upvalue的处理
robinlovemaggie
2014-01-13 17:11:30 +08:00
cbsw
2014-01-14 12:21:51 +08:00
@yuelang85 同感。python 代码还是不要直接贴在 V2EX 上,会把缩进吃掉,没有缩进的 Python 的代码没法看

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/96764

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX