Python2.7 中的另一个 UnboundLocalError

问题描述:

当我在公司的 Python 项目中执行测试脚本时,出现如下错误:

When I execute a testing script in my company's Python project, I got an error as below:

UnboundLocalError: local variable 'a' referenced before assignment

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

I wrote some simpler code to reproduce the issue, it has 2 files.

vars.py 文件:

vars.py file:

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

script.py 文件:

script.py file:

#!/usr/bin/env python
from vars import *


def myFunc1():
    print a

    if False:
        a = '111'

    print a

myFunc1()

执行代码:

$ 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 并找到了一些有用的信息,例如:

I googled the UnboundLocalError and found some useful information like:

UnboundLocalError:本地变量L"之前引用赋值 Python

Python 中的 UnboundLocalError

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

According to the answers in above 2 questions, if I add a global a after the def myFunc1(): line in script.py file, the error is gone.

我不明白的是从 myFunc1 中删除 if 条件也可以使它工作...

The thing I don't understand is removing the if condition from myFunc1 can also make it work...

给名字赋值会使名字成为局部变量,这意味着你不能在没有额外语法的情况下赋值给非局部变量.在您的代码中:

Assigning to a name makes the name a local variable, which means that you can't assign to a non-local variable without extra syntax. In your code:

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

myFunc1 的第一行添加 global a 将告诉 Python 当它看到对 a的赋值时它不应该创建局部变量代码>.它几乎肯定不会做你所期望的(假设你期望 vars 中的 a 被改变......).from vars import * 创建 vars 中名称的本地副本",并且使用 global 语句仅意味着您正在分配给 this 模块的 a 变量.其他导入 vars 的模块将看不到赋值.

adding global a as the first line in myFunc1 will tell Python that it shouldn't create a local variable when it sees an assignment to a. It will almost certainly not do what you expect though (assuming you expect the a in vars to be changed..). from vars import * creates local "copies" of the names in vars, and using the global statement just means that you are assigning to this module's a variable. Other modules that import vars will not see the assignment.

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

Removing the if statements also removes the assignment, which is why that eliminates the error.

我知道 from vars import * 和 using variables in thevars.py 不是一个好的设计......但我不能传递所有需要的变量到函数,因为函数可能使用 20 多个变量公司项目中的vars.py

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

不寒而栗...请重构.

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

For this particular problem you should use this pattern:

import vars

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