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

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


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


当前回答

如果要在函数中引用全局变量,可以使用global关键字声明哪些变量是全局变量。您不必在所有情况下都使用它(正如这里有人错误地宣称的那样)-如果表达式中引用的名称无法在定义该函数的函数的局部作用域中找到,则会在全局变量中查找该名称。

但是,如果您分配给函数中未声明为全局的新变量,则它将隐式声明为局部变量,并且它可能会覆盖同名的任何现有全局变量。

此外,全局变量是有用的,与一些OOP狂热者的说法相反——特别是对于较小的脚本,OOP是过度的。

其他回答

如果要在函数中引用全局变量,可以使用global关键字声明哪些变量是全局变量。您不必在所有情况下都使用它(正如这里有人错误地宣称的那样)-如果表达式中引用的名称无法在定义该函数的函数的局部作用域中找到,则会在全局变量中查找该名称。

但是,如果您分配给函数中未声明为全局的新变量,则它将隐式声明为局部变量,并且它可能会覆盖同名的任何现有全局变量。

此外,全局变量是有用的,与一些OOP狂热者的说法相反——特别是对于较小的脚本,OOP是过度的。

作为附加组件,使用一个文件来包含所有本地声明的全局变量,然后导入为:

文件initval.py:

Stocksin = 300
Prices = []

文件getstocks.py:

import initval as iv

def getmystocks(): 
    iv.Stocksin = getstockcount()


def getmycharts():
    for ic in range(iv.Stocksin):

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

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

def worker(new_value):
    old_value = get_value()
    set_value(random.randint(1, 99))
    print('pid=[{pid}] '
          'old_value=[{old_value:2}] '
          'new_value=[{new_value:2}] '
          'get_value=[{get_value:2}]'.format(
          pid=str(os.getpid()),
          old_value=old_value,
          new_value=new_value,
          get_value=get_value()))

def get_value():
    global global_variable
    return global_variable

def set_value(new_value):
    global global_variable
    global_variable = new_value

global_variable = -1

print('before set_value(), get_value() = [%s]' % get_value())
set_value(new_value=-2)
print('after  set_value(), get_value() = [%s]' % get_value())

processPool = multiprocessing.Pool(processes=5)
processPool.map(func=worker, iterable=range(15))

输出:

before set_value(), get_value() = [-1]
after  set_value(), get_value() = [-2]
pid=[53970] old_value=[-2] new_value=[ 0] get_value=[23]
pid=[53971] old_value=[-2] new_value=[ 1] get_value=[42]
pid=[53970] old_value=[23] new_value=[ 4] get_value=[50]
pid=[53970] old_value=[50] new_value=[ 6] get_value=[14]
pid=[53971] old_value=[42] new_value=[ 5] get_value=[31]
pid=[53972] old_value=[-2] new_value=[ 2] get_value=[44]
pid=[53973] old_value=[-2] new_value=[ 3] get_value=[94]
pid=[53970] old_value=[14] new_value=[ 7] get_value=[21]
pid=[53971] old_value=[31] new_value=[ 8] get_value=[34]
pid=[53972] old_value=[44] new_value=[ 9] get_value=[59]
pid=[53973] old_value=[94] new_value=[10] get_value=[87]
pid=[53970] old_value=[21] new_value=[11] get_value=[21]
pid=[53971] old_value=[34] new_value=[12] get_value=[82]
pid=[53972] old_value=[59] new_value=[13] get_value=[ 4]
pid=[53973] old_value=[87] new_value=[14] get_value=[70]

您可以在其他函数中使用全局变量,方法是在为其赋值的每个函数中将其声明为全局变量:

globvar = 0

def set_globvar_to_one():
    global globvar    # Needed to modify global copy of globvar
    globvar = 1

def print_globvar():
    print(globvar)     # No need for global declaration to read value of globvar

set_globvar_to_one()
print_globvar()       # Prints 1

由于不清楚globvar=1是创建本地变量还是更改全局变量,Python默认创建本地变量,并使用全局关键字显式选择其他行为。

如果要在模块间共享全局变量,请参阅其他答案。