Doubts about python variable scope
Possible Duplicate:
Short Description of Python Scoping Rules
我写了两个简单的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| # coding: utf-8
def test():
var = 1
def print_var():
print var
print_var()
print var
test()
# 1
# 1
def test1():
var = 2
def print_var():
print var
var = 3
print_var()
print var
test1()
# raise Exception |
相比之下,test1()在print var后赋值,然后提出一个例外:UnboundLocalError: local variable 'var' referenced before assignment,我认为当我调用内部print var时,var值为2,我错了吗?
- 请参见此链接:stackoverflow.com/questions/423379/…
- @汉森:不,global声明在这里没有帮助,因为var是一个函数范围变量。在python 3中,您可以使用nonlocal,但在python 2中(如这里所使用的),您无法完成op试图完成的工作。
是的,你这里不正确。函数定义引入了一个新的范围。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| # coding: utf-8
def test():
var = 1
def print_var():
print var <--- var is not in local scope, the var from outer scope gets used
print_var()
print var
test()
# 1
# 1
def test1():
var = 2
def print_var():
print var <---- var is in local scope, but not defined yet, ouch
var = 3
print_var()
print var
test1()
# raise Exception |
- 等等,我以为在执行时python没有向前看。python如何知道var将是第二个print_var函数中的局部变量?
- 因为错误发生在调用时,而不是函数定义时。如果您注释掉我指出的那条麻烦的行,那么我认为python确实会使用外部作用域中的var(=2)。
- 因此,当Python解析函数时,它会保存一个列表,其中包含分配给函数的所有变量的名称。然后在调用时,它看到var在这个列表中,并且由于它还没有定义而抱怨。是否可以访问此本地变量列表?
- @拉齐尔:没错;变量在编译时绑定到一个作用域。赋值是一个存储操作,并将该变量绑定到本地作用域,除非标记为全局。如果没有赋值,那么变量是"自由的",并在周围的作用域中查找,但它也绑定到特定的作用域。例如,请参见具有动态特性的python嵌套范围。
- 他说了些什么。而对var = 3的评论,将使test1()逻辑与test()逻辑基本相同。
- @martijn我可以访问函数的作用域并查看它的局部变量是什么?
- 您可以在函数内部使用locals()。在函数之外,这将很困难,因为python是动态的,但是您可以查看ast模块了解一些想法。
- @我指的是从外面的功能。我们已经建立了这样一个名单,但它在哪里?
- 您可以动态地向本地作用域添加或删除,这样就不那么简单了。
- 我想我看到了你现在所得到的,在执行print var的时候,我们有var not in locals(),但不知何故,python知道从外部使用var是不正确的。正确的?
- @Lazyr:是的,参见docs.python.org/reference/datamodel.html,afunction.func_code.co_varnames是局部变量。co_freevars和co_cellvars在这方面很有趣;它们分别是取自周围范围(非全局)的变量和嵌套函数引用的变量。
- WIM是对的。Martijn回答了我的问题,我发现这个答案详细描述了引发UnboundLocalError的词法分析过程。
- 谢谢马蒂。@拉齐尔的问题正危险地接近我的Python知识的边缘:)