如何在函数中创建或使用全局变量?

如何在其他函数中使用一个函数中定义的全局变量?


未能在适当的地方使用全局关键字通常会导致UnboundLocalError。在第一次使用后重新分配局部变量时,UnboundLocalError中解释了这方面的精确规则。一般来说,当寻求解释时,请将其他问题作为该问题的副本,当某人只需要知道全局关键字时,请关闭该问题。


当前回答

除了已经存在的答案之外,为了使这一问题更加令人困惑:

在Python中,仅在函数内部引用的变量是隐式全局。如果在任何地方为变量分配了新值在函数体中,假设它是局部的。如果变量如果在函数中分配了一个新值,则变量为隐式本地,您需要将其显式声明为“全局”。虽然一开始有点令人惊讶,但片刻的思考解释了这一方面,要求全局分配变量提供了防止意外的副作用。另一方面,如果全球对于所有全局引用都是必需的时间您必须将对内置函数或导入模块的组件。这种混乱会破坏全球宣言对识别副作用。

来源:Python中局部和全局变量的规则是什么?。

其他回答

实际上,您并没有将全局变量存储在本地变量中,只是创建了对原始全局引用引用的同一对象的本地引用。请记住,Python中的几乎所有内容都是引用对象的名称,在通常的操作中不会复制任何内容。

如果您不必显式指定标识符何时引用预定义的全局变量,那么您可能必须显式指定何时标识符是新的局部变量(例如,使用JavaScript中的“var”命令)。由于在任何严肃和非平凡的系统中,局部变量比全局变量更常见,因此Python的系统在大多数情况下更有意义。

你可能有一种语言试图猜测,如果存在的话使用一个全局变量,如果不存在的话创建一个局部变量。然而,这很容易出错。例如,导入另一个模块可能会无意中引入一个同名的全局变量,从而改变程序的行为。

您的意思是使用以下方法:

globvar = 5

def f():
    var = globvar
    print(var)

f()  # Prints 5

但更好的方法是像这样使用全局变量:

globvar = 5
def f():
    global globvar
    print(globvar)
f()   #prints 5

两者的输出相同。

全局变量很好-除了多处理

与不同平台/环境上的多处理相关的全局变量因为一边是Windows/Mac OS,另一边是Linux,这很麻烦。

我将用一个简单的例子向你展示这一点,指出我前段时间遇到的一个问题。

如果你想了解为什么Windows/MacOs和Linux上的情况不同需要知道的是,启动新进程的默认机制。。。

Windows/MacOs是“种子”Linux是“fork”

它们在内存分配和初始化方面有所不同。。。(但我不想谈这个此处)。

让我们看看这个问题/例子。。。

import multiprocessing

counter = 0

def do(task_id):
    global counter
    counter +=1
    print(f'task {task_id}: counter = {counter}')

if __name__ == '__main__':

    pool = multiprocessing.Pool(processes=4)
    task_ids = list(range(4))
    pool.map(do, task_ids)

窗户

如果你在Windows上运行这个(我想也是在MacOS上),你会得到以下输出。。。

task 0: counter = 1
task 1: counter = 2
task 2: counter = 3
task 3: counter = 4

Linux系统

如果您在Linux上运行此程序,则会得到以下结果。

task 0: counter = 1
task 1: counter = 1
task 2: counter = 1
task 3: counter = 1

写入全局数组的显式元素显然不需要全局声明,尽管“批发”写入它确实有这样的要求:

import numpy as np

hostValue = 3.14159
hostArray = np.array([2., 3.])
hostMatrix = np.array([[1.0, 0.0],[ 0.0, 1.0]])

def func1():
    global hostValue    # mandatory, else local.
    hostValue = 2.0

def func2():
    global hostValue    # mandatory, else UnboundLocalError.
    hostValue += 1.0

def func3():
    global hostArray    # mandatory, else local.
    hostArray = np.array([14., 15.])

def func4():            # no need for globals
    hostArray[0] = 123.4

def func5():            # no need for globals
    hostArray[1] += 1.0

def func6():            # no need for globals
    hostMatrix[1][1] = 12.

def func7():            # no need for globals
    hostMatrix[0][0] += 0.33

func1()
print "After func1(), hostValue = ", hostValue
func2()
print "After func2(), hostValue = ", hostValue
func3()
print "After func3(), hostArray = ", hostArray
func4()
print "After func4(), hostArray = ", hostArray
func5()
print "After func5(), hostArray = ", hostArray
func6()
print "After func6(), hostMatrix = \n", hostMatrix
func7()
print "After func7(), hostMatrix = \n", hostMatrix

我补充了这一点,因为我在其他任何答案中都没有看到它,它可能对正在与类似问题作斗争的人有用。globals()函数返回一个可变的全局符号字典,您可以在其中“神奇地”使数据可用于代码的其余部分。例如:

from pickle import load
def loaditem(name):
    with open(r"C:\pickle\file\location"+"\{}.dat".format(name), "rb") as openfile:
        globals()[name] = load(openfile)
    return True

and

from pickle import dump
def dumpfile(name):
    with open(name+".dat", "wb") as outfile:
        dump(globals()[name], outfile)
    return True

将只允许您将变量转储/加载到全局命名空间中。超级方便,没有麻烦,没有麻烦。很确定它只是Python 3。