如何在已定义变量后更改变量?

use*_*337 21 python scope python-3.x

我正在尝试添加或减去已定义的变量,但我无法弄清楚如何使用新值覆盖旧值.

a = 15

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

test()
Run Code Online (Sandbox Code Playgroud)

错误信息:

Traceback (most recent call last):
  File "test.py", line 7, in <module>
    test()
  File "test.py", line 4, in test
    a = a +10
UnboundLocalError: local variable 'a' referenced before assignment
Run Code Online (Sandbox Code Playgroud)

Zer*_*eus 27

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

UnboundLocalError: local variable 'a' referenced before assignment
Run Code Online (Sandbox Code Playgroud)

......从表面上看,它看起来很奇怪:毕竟,上面代码中的第一个语句(a = 15)是一个赋值.发生什么了?

实际上,发生了两件不同的事情,除非你已经了解它们,否则它们都不明显.

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

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

  • 将a在其他行是一个局部变量,也就是说,它只是你的内部存在test()功能.

这两个变量彼此完全无关,即使它们具有相同的名称.

变量是函数的本地变量,如果在该函数内有一个语句分配给它 - 例如,你的a = a +10行.

即便如此,错误仍然看起来很奇怪 - 毕竟,你在里面做的第一件事test()是分配给a,所以如何才能事先引用呢?

答案是,在一个赋值语句,Python的评估上的右手边一切=迹象在左侧将其分配给在名称前-所以即使分配是写在你的代码首先,a被引用在第一右手边:a +10.

有两种方法可以解决这个问题.第一个是告诉Python你真的希望a内部在全局范围内test()是相同a的:

def test():
    global a
    a = a + 10
    print(a)
Run Code Online (Sandbox Code Playgroud)

这可行,但编写程序是一种非常糟糕的方式.改变函数内部的全局变量很难快速管理,因为你通常有很多函数,而且没有人能够确定另一个函数没有以某种他们不期望的方式搞乱全局变量.

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

a = 15

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

test(a)
Run Code Online (Sandbox Code Playgroud)

请注意,名称不必相同 - 您的新定义test()只表示它接受一个值,然后对其执行某些操作.你可以传递你喜欢的任何东西 - 它可能是a,或者数字7,或其他东西.事实上,如果您尝试避免在不同范围内使用相同名称的变量,则您的代码将始终更容易理解.

如果你玩上面的代码,你会发现一些有趣的东西:

>>> a = 15
>>> test(a)
25
>>> a
15
Run Code Online (Sandbox Code Playgroud)

...... 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
Run Code Online (Sandbox Code Playgroud)

  • 在有人指出“x”实际上被“替换”而不是“改变”之前……我知道。不过,我已经必须覆盖相当多的基础才能正确回答这个问题,并决定不打开那个特定的蠕虫罐头。 (2认同)

Nud*_*din -4

您的错误与已定义的\xe2\x80\xa6 无关

\n

变量仅在其所谓的作用域内有效:如果在函数中创建变量,则该变量仅在该函数中定义。

\n
def test():\n   x = 17\n   print(x) # Returns 17\n\ntest()\nprint(x) # Results in an error.\n
Run Code Online (Sandbox Code Playgroud)\n