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

时间:2016-12-28 20:40:05

标签: python python-3.x scope

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

a = 15

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

test()

错误讯息:

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

8 个答案:

答案 0 :(得分:24)

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

UnboundLocalError: local variable 'a' referenced before assignment

...从表面上看,它看起来很奇怪:毕竟,上面代码中的第一个语句(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)

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

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

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

答案 1 :(得分:2)

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

a = 15

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

test()

答案 2 :(得分:2)

我会这样做:

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

print(test(15))

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

首先,我写下的内容会创建一个函数,作为输入,值 a (在这种情况下,当我们调用函数时,设置为15 - 已在最后一行中定义 - ),然后将对象 a 赋值 a (15为15)加10,然后返回 a (已修改,现在最后,由于最后一行代码,打印 a

print(test(15))

请注意,你所做的并不是一个纯粹的功能,可以这么说。通常我们希望函数获取输入值(或几个)并返回一个输入值(或几个)。在您的情况下,您有一个实际为空且没有输出值的输入值(因为您没有使用返回)。此外,你试图在函数外写这个输入 a (当你通过说test(a)来调用它时, a 没有加载时,你给了你错误 - 在电脑眼中,它是“空的”)。

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

至少,这是他们在基础编程课程中向我展示的方式。这可以证明如下:如果你在函数中使用返回,该函数将给你一个值,以后可以在其他函数中使用(即函数返回 s你可以使用的东西)。否则,您只能使用打印在屏幕上显示一个数字,但计算机无法继续使用它。

P.S。你也可以这样做:

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

print(test(15))

答案 3 :(得分:1)

a = 15

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

如果你想改变函数内局部变量的值,你需要使用 global 关键字。

答案 4 :(得分:0)

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

访问函数的局部全局变量
a = 15

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

test()

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

答案 5 :(得分:0)

这里的问题是范围。 该错误基本上意味着您正在使用变量 a,但它尚不存在。为什么?变量 a 尚未在 test() 函数中声明。使用前需要“邀请”全局变量。

有几种方法可以在函数作用域中包含变量。一种方法是将其用作这样的参数:

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

然后实现为:

test(a)

或者,您也可以使用 global 关键字来显示 a 是全局变量的函数。如何?像这样:

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

使用 global 关键字,只是告诉 test 在哪里寻找 a。 使用第一种方法,您无法修改全局变量 a,因为您制作了它的副本并且正在使用该副本。但是,第二种方法,您在函数 test()a 中所做的任何更改都会影响全局变量 a

答案 6 :(得分:-3)

# 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: ...

答案 7 :(得分:-5)

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

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

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