繁体   English   中英

如何从函数内部更改全局变量?

[英]How to change a global variable from within a function?

我正在尝试从定义的变量中添加或减去,但我不知道如何用新值覆盖旧值。

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

尝试运行代码时遇到的错误是:

UnboundLocalError: local variable 'a' referenced before assignment

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

实际上,有两种截然不同的事情正在发生,除非您已经了解它们,否则它们都不是显而易见的。

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

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

  • a在其他行是一个局部变量,也就是说,它只是你的内部存在test()函数。

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

如果在函数内部有赋值语句,则该变量是函数的局部变量 - 例如,您的a = a +10行。

即便如此,错误仍然看起来很奇怪——毕竟,你在test()做的第一件事就是赋值给a ,那么如何事先引用它呢?

答案是,在赋值语句中,Python 会先评估=符号右侧的所有内容,然后再将其赋值给左侧的名称——因此,即使代码中首先编写了赋值, a也会首先被引用在右手边: a +10

有两种方法可以解决这个问题。 第一个是告诉 Python 你真的希望a inside 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

我会这样做:

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

print(test(15))

请注意,在特此提出的版本中,有些内容与您的有所不同。

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

print(test(15))

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

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

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

PS你可以这样做:

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

print(test(15))

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

a = 15

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

test()
a = 15

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

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

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

a = 15

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

test()

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

这里的问题是范围。 该错误基本上意味着您正在使用变量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

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

你的错误与已经定义无关……一个变量只在它所谓的范围内有效:如果你在一个函数中创建一个变量,它只在这个函数中定义。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM