推荐学习书目
› 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 · Jan 13, 2014 · 5335 views
    This topic created in 4683 days ago, the information mentioned may be changed or developed.
    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 replies  •  1970-01-01 08:00:00 +08:00
    njustyw
    njustyw
    Jan 13, 2014
    1
    这个是闭包的问题吧
    woshifyz
    woshifyz
    Jan 13, 2014
    2
    因为python奇怪的lexical scope,当内部函数中只读同名变量时,它就是外部变量;但当你写同名变量时,它就是局部变量。python3 中添加nonlocal来解决这一问题

    你把 z=x+1 这行换成 x=10 就知道了
    jayn1985
    jayn1985
    OP
    Jan 13, 2014
    3
    @njustyw 能详细说说么?inner函数通过作用域链使用outer函数的变量x,这个我了解,但是和locals方法结合起来看,有点糊涂了,一直没弄明白#1的结果是如何生成的
    inyfee
    inyfee
    Jan 13, 2014
    4
    这个属于闭包的概念,x 此时属于自由变量
    jayn1985
    jayn1985
    OP
    Jan 13, 2014
    5
    @woshifyz 你说的这个我理解,我困惑的主要是在#1这行语句执行之前,并没有对变量x的读操作啊,为啥locals还能输出x呢?或者这个说,为啥y没有输出来但是却输出x了呢?
    woshifyz
    woshifyz
    Jan 13, 2014
    6
    @jayn1985 先有编译,后有执行
    winfred
    winfred
    Jan 13, 2014
    7
    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
    jayn1985
    OP
    Jan 13, 2014
    8
    @woshifyz 感谢指点,这个跟js的预编译是一样的概念么?如果预编译可以得知变量x,为啥变量z却没有输出呢?还是有些糊涂。。。
    yuelang85
    yuelang85
    Jan 13, 2014
    9
    能用gist排下版吗?完全不明白楼主意图
    woshifyz
    woshifyz
    Jan 13, 2014
    10
    @jayn1985 因为那个时候变量z还没有定义,而python在编译成opcode的时候就已经知道x是只读的,所以在inner中可以引用outer中的x,你可以理解为inner默认有一个const x=1,关于此,你可以看看lua中upvalue的处理
    cbsw
    cbsw
    Jan 14, 2014
    12
    @yuelang85 同感。python 代码还是不要直接贴在 V2EX 上,会把缩进吃掉,没有缩进的 Python 的代码没法看
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   955 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 19:53 · PVG 03:53 · LAX 11:53 · JFK 14:53
    ♥ Do have faith in what you're doing.