关于python:为什么我在赋值错误之前得到一个局部变量?

Why am I getting a local variable referenced before assignment error?

本问题已经有最佳答案,请猛点这里访问。

答案应该是2,因为首先调用main()函数,然后调用first()函数,覆盖在任何函数之外定义的全局变量num=0,因此使其成为具有全局范围的变量。但我得到了以下错误:

1
UnboundLocalError: local variable 'num' referenced before assignment

为什么我会得到这个错误?

1
2
3
4
5
6
7
8
9
10
11
12
13
def first():
    num = num + 1

def main():
    num = 1
    first()
    print(num)

num = 0

num_result = main()

print(num_result)

这首诗写的(强调我的):

The answer should be 2 because first the main() function is called, then the first() function is called, overriding the global variable.

它不会覆盖全局变量。除非显式地将变量指定为全局变量,否则如果函数中存在对变量的赋值,则假定该变量为局部变量。另请参见关于定义其状态函数的python教程(emphasis mine):

More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table of built-in names. Thus, global variables cannot be directly assigned a value within a function (unless named in a global statement), although they may be referenced.

以及global语句的文档(如果有人使用python 3查看此内容,请查看(与global相比)非常有用的nonlocal语句及其PEP 3104)。

要"修复"您的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def first():
    global num
    num = num + 1

def main():
    global num
    num = 1
    first()
    print(num)

num = 0

num_result = main()

print(num_result)

请不要以这种方式使用全局变量。@路德霍恩已经在他的回答中表明了如何正确地做这件事。

避免全局变量的原因是,它们的效果很难测试,一旦代码变得足够复杂,就很难解释。如果每个函数都修改全局变量,而不是正确地获取参数和返回值,那么只要与代码保持一周左右的距离,就很难理解代码的实际操作。


first内,不知道num。使用自变量和return语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
def first(num):
    return num + 1

def main():
    num = 1
    num = first(num)
    return num

num = 0

num_result = main()

print(num_result)


变量num刚刚在main方法中初始化,而不是在first()-方法中初始化。所以你必须把它交给第一个()-方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
def first(num):
    return num + 1

def main():
    num = 1
    num = first(num)
    return num

num = 0

num_result = main()

print(num_result)


"num"未在函数"first"中定义。它不是一个全局变量,超出了"第一"的范围。要使其全局化,只需按如下方式编辑函数:

1
2
3
def first():
    global num
    num = num + 1

在我看来,使用全局变量是不好的做法。您可以通过使用参数和这样的返回来实现相同的目的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def first(num):
    return num + 1

def main(num):
    num = 1
    num = first(num)
    print(num)
    return num

num = 0

num_result = main(num)

print(num_result)


这是范围错误。首先,在尝试向其中添加num之前,没有num。如果变量在此块中声明、在上块中声明或声明为全局变量,则可以调用块中的变量。

要传递变量,可以使用函数的参数:

1
2
3
4
5
6
def first(num):
    return num + 1

def main():
    shmilblik = first(1)
    print(shmilblik)