关于python:Python2.7中的另一个UnboundLocalError

Another UnboundLocalError in Python2.7

当我在公司的python项目中执行一个测试脚本时,我得到一个错误,如下所示:

1
UnboundLocalError: local variable 'a' referenced before assignment

我写了一些简单的代码来重现这个问题,它有两个文件。

Val.Py文件:

1
2
#!/usr/bin/env python
a = 'aaa'

脚本文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python
from vars import *


def myFunc1():
    print a

    if False:
        a = '111'

    print a

myFunc1()

执行代码:

1
2
3
4
5
6
7
8
9
10
$ python --version
Python 2.7.10
$ python script.py
Traceback (most recent call last):
  File"script.py", line 13, in <module>
    myFunc1()
  File"script.py", line 6, in myFunc1
    print a
UnboundLocalError: local variable 'a' referenced before assignment
$

我搜索了UnboundLocalError,发现了一些有用的信息,比如:

UnboundLocalError:在赋值python之前引用了局部变量"l"

python中的unboundlocalerror

根据以上2个问题的答案,如果在script.py文件中的def myFunc1():行后面加一个global a,错误就消失了。

我不明白的是把if条件从myFunc1中去掉也能使它工作…


分配给名称会使名称成为局部变量,这意味着如果没有额外的语法,就无法分配给非局部变量。在您的代码中:

1
2
3
4
5
6
7
from vars import *

def myFunc1():
    print a         # the local variable `a` is used before it is created
    if False:
        a = '111'   # this creates a local variable `a`
    print a

添加global a作为myFunc1中的第一行将告诉python,当它看到对a的赋值时,不应该创建局部变量。它几乎肯定不会像您所期望的那样(假设您希望vars中的a会被更改)。from vars import *创建vars中名称的本地"副本",使用global语句只意味着您要分配给该模块的a变量。其他导入vars的模块将看不到分配。

删除if语句也会删除赋值,这就是消除错误的原因。

I understand that from vars import * and using variables in the
vars.py is not a good design... But I can't pass all needed variables
to the function since the function may use 20+ variables from the
vars.py in company's project

战栗请重构。

对于这个特定的问题,您应该使用这个模式:

1
2
3
4
5
6
7
import vars

def myFunc1():
    print vars.a
    if False:
        vars.a = '111'
    print vars.a


您应该将值传递给函数,而不是依赖全局变量。同样,如果"假"实际上不起作用,因为它总是返回"真"。您可能想说,如果变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python
from vars import *


def myFunc1(x):
    print x

    if x:
        x = '111'

    print x

myFunc1(a)