Python函数作用域导入

时间:2013-04-04 12:41:12

标签: python python-import

我有以下模块:

main.py

import my_import

my_import.a_func()

my_import.py

FOO = "foo"
BAR = []

def a_func():
   BAR.append("bar") #ok
   FOO = FOO + "foo" #UnboundLocalError: 
                     #local variable 'FOO' referenced before assignment

这可能是由于导入,但是如何?

[编辑]

从答案我得到的不是导入的crulpit,但是后续仍然很奇怪:

FOO = "foo"
BAR = []
def a_func():
    BAR.append("bar")
    print(FOO)
a_func()

- >打印“foo”

FOO = "foo"
BAR = []
def a_func():
    BAR.append("bar")
    print(FOO)
    FOO = FOO + "foo"    
a_func()

- >失败,“UnboundLocalError:在赋值之前引用了局部变量'FOO'并且没有打印”foo“

看起来解释器在实际运行代码之前正在查找当前作用域中的赋值。

3 个答案:

答案 0 :(得分:5)

当Python解析函数定义时,它会记录赋值语句左侧的所有变量名,例如

FOO = FOO + "foo"

它将所有此类变量名称注册为局部变量

让我强调一下,赋值语句会导致Python在解析函数定义时将FOO注册为局部变量,而不是在调用函数时。所以稍后,当调用该函数时,即使对在赋值之前发生的FOO的引用仍然引用局部变量并且可以引发UnboundLocalError

def a_func():
    BAR.append("bar")
    print(FOO)       #<--- "Freaky" UnboundLocalError occurs here!
    FOO = FOO + "foo" 

所以在a_func内,FOO是一个局部变量。在没有print(FOO)语句的情况下,Python到达赋值并首先评估右侧。遇到变量名称FOO,将其识别为局部变量并询问其值是多少?它没有价值!所以它引发了UnboundLocalError

要解决此问题,请使用global FOO声明FOO内的a_func引用全局变量:

FOO = "foo"
BAR = []

def a_func():
   global FOO
   BAR.append("bar") #ok
   FOO = FOO + "foo" assignment

相比之下,BAR.append('bar')有效,因为Python首先查找变量BAR - 它不认为它是局部变量,因为没有赋值BAR = ...。它在全局范围内找到BAR,然后查找其append方法,然后改变BAR。因此,您可以改变BAR但不能分配给FOO(没有global FOO语句。)

答案 1 :(得分:2)

不,它与导入无关。它也会发生在单个模块或脚本中,即使在交互式解释器中也是如此。

最小的例子是

a = 1
def f():
    a = a + 1

此分配使a成为局部变量。在这种情况下,全局的一个被遮蔽,因此无法访问。

如果您想更改全局版本,可以使用global解决此问题:

a = 1
def f():
    global a
    a = a + 1
如果要在本地保留更改,请使用

或使用不同名称的本地变量:

a = 1
def f():
    b = a
    b = b + 1

答案 2 :(得分:0)

我可能是错的,但FOO和BAR的范围可能是问题吗?看起来好像您已进入不同的范围。尝试将方法中的FOO和BAR标记为全局。