V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
jayn1985
V2EX  ›  Python

一个Python语法问题求解惑

  •  
  •   jayn1985 · 2014-01-13 10:40:32 +08:00 · 3881 次点击
    这是一个创建于 3755 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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)
    12 条回复    1970-01-01 08:00:00 +08:00
    njustyw
        1
    njustyw  
       2014-01-13 10:49:29 +08:00
    这个是闭包的问题吧
    woshifyz
        2
    woshifyz  
       2014-01-13 10:51:04 +08:00
    因为python奇怪的lexical scope,当内部函数中只读同名变量时,它就是外部变量;但当你写同名变量时,它就是局部变量。python3 中添加nonlocal来解决这一问题

    你把 z=x+1 这行换成 x=10 就知道了
    jayn1985
        3
    jayn1985  
    OP
       2014-01-13 10:55:27 +08:00
    @njustyw 能详细说说么?inner函数通过作用域链使用outer函数的变量x,这个我了解,但是和locals方法结合起来看,有点糊涂了,一直没弄明白#1的结果是如何生成的
    yeelone
        4
    yeelone  
       2014-01-13 10:57:31 +08:00
    这个属于闭包的概念,x 此时属于自由变量
    jayn1985
        5
    jayn1985  
    OP
       2014-01-13 10:59:45 +08:00
    @woshifyz 你说的这个我理解,我困惑的主要是在#1这行语句执行之前,并没有对变量x的读操作啊,为啥locals还能输出x呢?或者这个说,为啥y没有输出来但是却输出x了呢?
    woshifyz
        6
    woshifyz  
       2014-01-13 11:06:30 +08:00
    @jayn1985 先有编译,后有执行
    winfred
        7
    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
        8
    jayn1985  
    OP
       2014-01-13 13:36:11 +08:00
    @woshifyz 感谢指点,这个跟js的预编译是一样的概念么?如果预编译可以得知变量x,为啥变量z却没有输出呢?还是有些糊涂。。。
    yuelang85
        9
    yuelang85  
       2014-01-13 14:06:34 +08:00
    能用gist排下版吗?完全不明白楼主意图
    woshifyz
        10
    woshifyz  
       2014-01-13 14:09:44 +08:00
    @jayn1985 因为那个时候变量z还没有定义,而python在编译成opcode的时候就已经知道x是只读的,所以在inner中可以引用outer中的x,你可以理解为inner默认有一个const x=1,关于此,你可以看看lua中upvalue的处理
    robinlovemaggie
        11
    robinlovemaggie  
       2014-01-13 17:11:30 +08:00
    cbsw
        12
    cbsw  
       2014-01-14 12:21:51 +08:00
    @yuelang85 同感。python 代码还是不要直接贴在 V2EX 上,会把缩进吃掉,没有缩进的 Python 的代码没法看
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3574 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 10:54 · PVG 18:54 · LAX 03:54 · JFK 06:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.