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

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


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


当前回答

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

与不同平台/环境上的多处理相关的全局变量因为一边是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

其他回答

如果我在一个函数中创建一个全局变量,我如何在另一个函数上使用该变量?

我们可以使用以下函数创建全局:

def create_global_variable():
    global global_variable # must declare it to be a global first
    # modifications are thus reflected on the module's global scope
    global_variable = 'Foo' 

编写函数实际上不会运行其代码。因此我们调用create_global_variable函数:

>>> create_global_variable()

使用全局变量而不进行修改

只要您不希望更改它指向的对象,就可以使用它:

例如

def use_global_variable():
    return global_variable + '!!!'

现在我们可以使用全局变量:

>>> use_global_variable()
'Foo!!!'

从函数内部修改全局变量

要将全局变量指向其他对象,需要再次使用全局关键字:

def change_global_variable():
    global global_variable
    global_variable = 'Bar'

请注意,在编写此函数后,实际更改它的代码仍然没有运行:

>>> use_global_variable()
'Foo!!!'

因此,调用函数后:

>>> change_global_variable()

我们可以看到全局变量已经改变。global_variable名称现在指向“Bar”:

>>> use_global_variable()
'Bar!!!'

请注意,Python中的“全局”并不是真正的全局-它只是模块级的全局。因此,它只适用于在全局模块中编写的函数。函数会记住编写它们的模块,因此当它们导出到其他模块中时,它们仍然会查找创建它们的模块以查找全局变量。

同名的局部变量

如果创建同名的局部变量,它将覆盖全局变量:

def use_local_with_same_name_as_global():
    # bad name for a local variable, though.
    global_variable = 'Baz' 
    return global_variable + '!!!'

>>> use_local_with_same_name_as_global()
'Baz!!!'

但使用该错误命名的局部变量不会更改全局变量:

>>> use_global_variable()
'Bar!!!'

请注意,您应该避免使用与全局变量同名的局部变量,除非您确切地知道自己在做什么,并且有充分的理由这样做。我还没有遇到这样的原因。

我们在课堂上也有同样的行为

后续评论问道:

如果我想在类内的函数内创建一个全局变量,并想在另一个类内的另一个函数内使用该变量,该怎么办?

在这里,我演示了我们在方法中得到的行为与在正则函数中得到的相同:

class Foo:
    def foo(self):
        global global_variable
        global_variable = 'Foo'

class Bar:
    def bar(self):
        return global_variable + '!!!'

Foo().foo()

现在:

>>> Bar().bar()
'Foo!!!'

但我建议不要使用全局变量,而是使用类属性,以避免混淆模块名称空间。还要注意,我们这里不使用self参数-这些可以是类方法(如果从通常的cls参数中更改class属性,则很方便)或静态方法(没有self或cls)。

global_var = 10  # will be considered as a global variable


def func_1():
    global global_var  # access variable using variable keyword
    global_var += 1


def func_2():
    global global_var
    global_var *= 2
    print(f"func_2: {global_var}")


func_1()
func_2()
print("Global scope:", global_var) # will print 22

说明:

globalvar是一个全局变量,所有函数和类都可以访问该变量。

func_1()使用关键字global访问该全局变量,该关键字指向写入全局范围的变量。如果我没有写全局关键字,func_1内的变量global_var被认为是一个局部变量,只能在函数内使用。然后在func_1内,我将全局变量递增1。

在func_2()中也发生了同样的情况。

调用func_1和func_2后,您将看到global_var已更改

如果您有一个同名的局部变量,您可能需要使用globals()函数。

globals()['your_global_var'] = 42

我补充了这一点,因为我在其他任何答案中都没有看到它,它可能对正在与类似问题作斗争的人有用。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。

如果要访问全局变量,只需在函数中添加全局关键字前任:global_var=“是”

def someFunc():
   global global_var;
   print(nam_of_var)