Python:在赋值后引用时抛出神秘的“赋值前引用”错误

时间:2015-01-20 00:50:41

标签: python

file1.py:

a = 2;

class adder():

    def __init__(self):
        a = a;
        a = a % 5;
        print a;

实例化adder()会导致“UnboundLocalError: local variable 'a' referenced before assignment”,但如果我将init更改为:

def __init__(self):

     print a;

然后我没有错误。

2 个答案:

答案 0 :(得分:5)

如果a = ...(或任何其他形式的作业,如for a in ...)在函数正文中出现 ,那么a将成为本地的整个功能。您不能将变量部分地设为全局变量,部分变为局部变量。

因此,您有一个名为a的本地人,并且您正在尝试分配a = a。 Python需要做的第一件事是在右侧找出a的值...但是a是尚未分配给它的本地。因此错误。

只需使用其他变量名称即可。如果你真的想要改变外部a(在构造函数中有腥味!),你必须用global a声明你的意图。

另外,在Python的行尾不需要分号。如果这是Python 2,那么您的类应该继承自object(如class Adder(object):中所述),否则您将获得一个旧的"具有不同行为但在以后的Python版本中不存在的类。

答案 1 :(得分:2)

您需要使用全局语句将模块级全局变量拉入范围:

a = 2

class adder():
    def __init__(self):
        global a # need this!
        # a = a # don't need this
        a = a % 5 # assigning to `a` would be otherwise ambiguous without
                  # the global statement
        print a

您不需要分号。

最好是使用默认参数,例如这样,以避免在全局层面上改变事物。:

a = 2

class adder():
    def __init__(self, a=a):
        # don't need global statement since we're going to default to 
        # the global a.
        # a = a # don't need this
        a = a % 5
        print a

另一个更好的方法是在全球和地方层面使用不同的名称。我会重命名全局变量,并保持局部变量相同。我们倾向于大写(全部大写)全局常量(并大写类名,并从对象继承),因此可能如下所示:

A = 2

class Adder(object):
    def __init__(self):
        a = A % 5
        print a