Python变量作用域如何工作?

时间:2010-06-28 09:12:11

标签: python parsing scope grammar

这要求我深入挖掘Python资源,但由于SO上有很多人已经这样做了,我很乐意听到他们的指示。

>>> 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

在我看来,当解析器解释文件时,它会自动为范围函数创建本地范围,这使得os与全局范围“分离”。

这是真的吗?有人关心我在哪里可以找到有关范围实施的更多信息吗?

编辑:此外,这不是导入的特例,这也适用于通常的变量。

3 个答案:

答案 0 :(得分:5)

当您调用scope()时,Python会发现您的方法中使用了一个名为os的局部变量(来自import scope内的os),因此这会掩盖全局{ {1}}。但是,当您说print os时尚未到达该行并执行本地导入时,您会在分配前看到有关参考的错误。以下是其他一些可能有用的示例:

>>> 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

回到你的os示例。对os的任何分配都具有相同的效果:

>>> 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

最后,比较这两个例子:

>>> 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

答案 1 :(得分:1)

词法范围是一种常见的东西,设计最好的语言,无论是解释还是编译都使用它。

我有一段时间没试过这个,但请注意漂亮的“global”关键字及其在下面的用法:

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

没有“全局”行,对o的修改是本地化的,并且“print o”打印1.包含“global o”行,它打印2.我们称之为我的函数(没有全局o) )上面会有自己的变量。上面的全局内容是一种专门请求正常词法范围的例外的方法。

真正的词法范围是Python 1.0缺少的东西,以及Python已经存在了很长时间(至少1.6,如果我没记错的话)。只有两个范围,本地和全球,任何中间范围都无法访问。

答案 2 :(得分:0)

函数内部变量的任何绑定都会使该变量本地变量。 importdefclass等同于此方面的任务。

所以是的,当编译器编译你的文件时,它会创建一个局部变量os,它与全局os分开作用。

有关详细信息,请参阅Python教程。特别是http://docs.python.org/tutorial/classes.html第9.2节