代码之家  ›  专栏  ›  技术社区  ›  Almad

How does Python variable scoping works?

  •  4
  • Almad  · 技术社区  · 14 年前

    这需要我更深入地挖掘Python源代码,但是因为有很多人已经这样做了,所以我希望听到他们的指针。

    >>> import os
    >>> def scope():
    ...     print os
    ...     import os
    ... 
    >>> scope()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in scope
    UnboundLocalError: local variable 'os' referenced before assignment
    

    It seems to me that when parser interprets the file, it automatically creates local scope for scope function, that makes os "detached" from global scope.

    是真的吗?Anyone care to point me where I can find more about scope implementation?

    EDIT: Also, this is not special case of imports, this works for usual variables too.

    3 回复  |  直到 14 年前
        1
  •  5
  •   mikej heading_to_tahiti    14 年前

    当你打电话 scope() Python sees that you have a local variable called os used inside your method (from the import 里面 scope ) so this masks the global 操作系统 . However when you say print os you haven't reached the line and executed the local import yet so you see the error regarding reference before assignment. Here are a couple of other examples that might help:

    >>> x = 3
    >>> def printx():
    ...     print x # will print the global x
    ...
    >>> def printx2():
    ...     print x # will try to print the local x
    ...     x = 4
    ...
    >>> printx()
    3
    >>> printx2()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in printx2
    UnboundLocalError: local variable 'x' referenced before assignment
    

    And going back to your 操作系统 例子。Any assignment to 操作系统 has the same effect:

    >>> os
    <module 'os' from 'C:\CDL_INSTALL\install\Python26\lib\os.pyc'>
    >>> def bad_os():
    ...     print os
    ...     os = "assigning a string to local os"
    ...
    >>> bad_os()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in bad_os
    UnboundLocalError: local variable 'os' referenced before assignment
    

    Finally, compare these 2 examples:

    >>> def example1():
    ...     print never_used # will be interpreted as a global
    ...
    >>> def example2():
    ...     print used_later # will be interpreted as the local assigned later
    ...     used_later = 42
    ...
    >>> example1()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in example1
    NameError: global name 'never_used' is not defined
    >>> example2()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in example2
    UnboundLocalError: local variable 'used_later' referenced before assignment
    
        2
  •  1
  •   Warren P    14 年前

    词法范围界定是一种常见的事情,大多数设计良好的语言,无论是解释的还是编译的都会使用它。

    I had not tried this in a while, but note the nifty "global" keyword, and its use below:

    o = 1
    def foo():
        global o
        o = 2
    foo()
    print o
    

    Without the "global" line, the modification to o is localized, and "print o" prints 1. With the "global o" line included, it prints 2. We call this way that my function (without the global o) above would have its own variables. The global thing above is a way to specifically request an exception to the normal lexical scoping.

    True lexical scoping is something that Python 1.0 lacked, and which Python has had for a long time (since at least 1.6, if I remember correctly). There were only two scopes, local and global, and any intermediate scopes were inaccessible.

        3
  •  0
  •   Duncan    14 年前

    函数内变量的任何绑定都会使该变量成为该函数的局部变量。 import , def class are all equivalent to assignment in this respect.

    So yes, when the compiler compiles your file it creates a local variable os 它的作用域与全局 操作系统 .

    See the Python tutorial for more information. 特别地 http://docs.python.org/tutorial/classes.html 第9.2节