关于python:如何在定义变量之后更改它?

How to change a variable after it is already defined?

我正在尝试从一个定义的变量中进行加减运算,但是我不知道如何用新的变量覆盖旧的值。

1
2
3
4
5
6
7
a = 15

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

test()

错误信息:

1
2
3
4
5
6
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


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

1
UnboundLocalError: local variable 'a' referenced before assignment

…从表面上看,这似乎很奇怪:毕竟,上面代码中的第一个语句(a = 15是一个赋值。那么,怎么了?

实际上,有两种截然不同的事情发生了,除非你已经知道了,否则它们都不明显。

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

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

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

这两个变量完全不相关,即使它们具有相同的名称。

如果在函数内部有一个指定给它的语句,那么变量就是该函数的局部变量——例如,您的a = a +10行。

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

答案是,在赋值语句中,python在将=符号的右边的所有内容赋值给左边的名称之前对其进行评估——因此,即使赋值是在代码中首先写入的,a也会在右边首先被引用:a +10

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

1
2
3
4
def test():
    global a
    a = a + 10
    print(a)

这是可行的,但这是编写程序的一种非常糟糕的方法。改变函数内部的全局变量很难真正快速地进行管理,因为您通常拥有许多函数,而且它们中没有一个可以确保另一个函数不会以某种方式干扰它们不期望的全局变量。

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

1
2
3
4
5
6
7
a = 15

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

test(a)

注意,名称不一定是相同的——你对test()的新定义只是说它接受一个值,然后用它做一些事情。你可以输入任何你喜欢的东西——可以是a,或者是7或者其他什么。事实上,如果您试图避免在不同的范围中使用相同名称的变量,那么您的代码总是更容易理解的。

如果你玩上面的代码,你会注意到一些有趣的事情:

1
2
3
4
5
>>> a = 15
>>> test(a)
25
>>> a
15

a没有改变!这是因为虽然你把它传给了test(),它被分配给了x,但是当时x发生了变化,只剩下原来的a

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

1
2
3
4
5
6
7
8
9
10
11
>>> a = 15
>>>
>>> def test(x):
...     x = x + 10
...     print(x)
...     return x
...
>>> a = test(a)
25
>>> a
25


我会这样做:

1
2
3
4
5
def test(a):
    a = a +10
    return a

print(test(15))

请注意,在此提出的版本中有一些与您的不同之处。

首先,我写下的内容将创建一个函数,作为输入值a(在本例中,当我们调用函数时设置为15,在最后一行中已经定义了),然后将值a(15)加10赋给对象a,然后返回a(已经修改,现在是25),最后,由于最后一行COD,输出E:

1
print(test(15))

注意,你所做的并不是一个纯粹的函数,可以说。通常我们希望函数获取一个输入值(或多个)并返回一个输入值(或多个)。在您的例子中,您有一个实际上是空的输入值,没有输出值(因为您没有使用RETURN)。此外,您试图在函数外部编写这个输入(当您通过说test(a)来调用它时,值a没有被加载,这会给您带来错误,即在计算机的眼中,它是"空的")。

此外,我鼓励您习惯于在函数中编写返回,然后在调用它时使用打印(就像我在最后一行编码中所写的那样:print(test(15))),而不是在函数中使用它。最好只在调用函数并想查看函数实际执行的操作时使用print。

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

另外,你也可以这样做:

1
2
3
4
5
def test(a):
    a +=10      
    return a

print(test(15))


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

1
2
3
4
5
6
7
8
a = 15

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

test()


除非使用关键字global明确定义,否则变量的范围是块的局部范围。还有其他方法可以使用globals函数访问函数的局部全局变量。

1
2
3
4
5
6
7
8
a = 15

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

test()

上面的示例将打印25,同时保持全局值不变,即15


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# All the mumbo jumbo aside, here is an experiment
# to illustrate why this is something useful
# in the language of Python:
a = 15    # This could be read-only, should check docs

def test_1():
    b = a + 10    # It is perfectly ok to use 'a'
    print(b)

def test_2():
    a = a + 10    # Refrain from attempting to change 'a'
    print(a)

test_1()    # No error
test_2()    # UnboundLocalError: ...

您的错误与正在定义的无关…变量仅在其所谓的范围内有效:如果在函数中创建变量,则仅在此函数中定义。

1
2
3
4
5
6
def test():
   x=17
   print(x) # returns 17

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