Python 如何从函数中更改全局变量?

Python 如何从函数中更改全局变量?,python,python-3.x,scope,Python,Python 3.x,Scope,我试图对定义的变量进行加减运算,但我不知道如何用新值覆盖旧值 a = 15 def test(): a = a +10 print ( a ) test() 错误消息: 回溯(最近一次呼叫最后一次): 文件“test.py”,第7行,在 测试() 文件“test.py”,第4行,在测试中 a=a+10 UnboundLocalError:赋值前引用的局部变量“a” 您的错误与已定义的内容无关… 变量仅在其所谓的作用域内有效:如果在函数中创建变量,则该变量仅在此函数中定义 d

我试图对定义的变量进行加减运算,但我不知道如何用新值覆盖旧值

a = 15

def test():
    a = a +10
    print ( a )

test()
错误消息:

回溯(最近一次呼叫最后一次):
文件“test.py”,第7行,在
测试()
文件“test.py”,第4行,在测试中
a=a+10
UnboundLocalError:赋值前引用的局部变量“a”

您的错误与已定义的内容无关… 变量仅在其所谓的作用域内有效:如果在函数中创建变量,则该变量仅在此函数中定义

def test():
   x=17
   print(x) # returns 17

test()
print(x) # results in an error.

您正在修改在函数
test()
范围内创建的变量
a
。如果您想修改outter
a
,可以执行以下操作:

a = 15

def test():
    global a
    a = a + 1
    print(a)

test()

尝试运行代码时出现的错误是:

UnboundLocalError: local variable 'a' referenced before assignment
…从表面上看,这似乎很奇怪:毕竟,上面代码中的第一条语句(
a=15
)是赋值。那么,发生了什么事

事实上,有两种截然不同的事情正在发生,除非你已经知道它们,否则它们都不是显而易见的

首先,实际上有两个不同的变量:

  • 第一行中的
    a
    是一个全局变量(之所以称为全局变量,是因为它存在于全局范围内,任何函数定义之外)

  • 其他行中的
    a
    是一个局部变量,这意味着它只存在于
    test()函数中

  • def test():
       x=17
       print(x) # returns 17
    
    test()
    print(x) # results in an error.
    
这两个变量彼此完全无关,即使它们有相同的名称

如果函数内部有一个赋值语句,则变量是函数的局部变量,例如,
A=A+10

即使如此,错误看起来还是很奇怪-毕竟,您在
test()
中做的第一件事就是分配给
a
,那么如何事先引用它呢

答案是,在赋值语句中,Python先计算
=
符号右侧的所有内容,然后再将其分配给左侧的名称–因此,即使赋值是在代码中首先写入的,
a
在右侧首先被引用:
a+10

有两种方法可以解决这个问题。第一个是告诉Python,您确实希望
test()
内部的
a
在全局范围内是相同的
a

def test():
    global a
    a = a + 10
    print(a)
这是可行的,但这是一种非常糟糕的程序编写方法。改变函数中的全局变量变得很难快速管理,因为你通常有很多函数,而且没有一个函数能确保另一个函数不会以他们不期望的方式干扰全局变量

更好的方法是将变量作为参数传递给函数,如下所示:

a = 15

def test(x):
    x = x + 10
    print(x)

test(a)
请注意,名称不必相同-您对
test()
的新定义只是说它接受一个值,然后用它做一些事情。您可以传入任何您喜欢的内容–可以是
a
,也可以是编号
7
,或者其他内容。事实上,如果您试图避免在不同的作用域中使用相同名称的变量,那么代码总是更容易理解

如果您使用上面的代码,您会注意到一些有趣的事情:

>>> a = 15
>>> test(a)
25
>>> a
15
a
没有改变!这是因为,尽管您将其传递到
test()
并将其分配给
x
,但随后是
x
发生了更改,保留了原始的
a

如果要实际更改
a
,则需要从函数返回修改后的
x
,然后在外部将其重新分配回
a

>>> a = 15
>>> 
>>> def test(x):
...     x = x + 10
...     print(x)
...     return x
... 
>>> a = test(a)
25
>>> a
25

我会这样做:

def test(a):
    a = a +10
    return a

print(test(15))
请注意,在此提出的版本中有一些与您的不同之处

首先,我写下的内容将创建一个函数,该函数的输入值为a(在本例中,当我们调用该函数时设置为15-已在最后一行中定义-),然后将值a分配给对象a(15)加10,然后返回a(已修改,现在是25)最后,由于最后一行代码,打印出a

print(test(15))
请注意,您所做的实际上并不是一个纯函数。通常我们希望函数获取一个(或多个)输入值并返回一个(或多个)输入值。在您的情况下,您的输入值实际上为空,没有输出值(因为您没有使用返回)。此外,您试图将该输入a写入函数外部(当您通过说
test(a)
调用该函数时,a值未加载,这给了您一个错误-即在计算机眼中它是“空的”)

此外,我鼓励您习惯于在函数中编写return,然后在调用它时使用print(就像我在最后一行代码中写的:
print(test(15))
)与其在函数内部使用它,不如只在调用函数并希望查看函数实际执行的操作时使用print

至少,这是他们在基础编程课程中向我展示的方式。这可以证明如下:如果您在函数中使用return,函数将为您提供一个值,该值以后可以在其他函数中使用(即函数returns您可以使用的内容)。否则,您只能在屏幕上显示一个带有打印的数字,但计算机无法进一步使用它

另外,你也可以这样做:

def test(a):
    a +=10      
    return a

print(test(15))

变量的作用域是块的局部变量,除非使用关键字
global
明确定义。还有其他方法可以使用
globals
functi访问函数的局部全局变量
a = 15

def test():
    a = globals()['a']
    a += 10
    print ( a )

test()
a = 15

def test():
    global a
    a = a +10
    print ( a )
    
test()