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

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


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


当前回答

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已更改

其他回答

Python使用一个简单的启发式方法来决定应该从哪个范围加载变量,在本地和全局之间。如果变量名出现在赋值的左侧,但未声明为全局变量,则假定它是局部变量。如果它没有出现在赋值的左侧,则假定它是全局的。

>>> import dis
>>> def foo():
...     global bar
...     baz = 5
...     print bar
...     print baz
...     print quux
... 
>>> dis.disassemble(foo.func_code)
  3           0 LOAD_CONST               1 (5)
              3 STORE_FAST               0 (baz)

  4           6 LOAD_GLOBAL              0 (bar)
              9 PRINT_ITEM          
             10 PRINT_NEWLINE       

  5          11 LOAD_FAST                0 (baz)
             14 PRINT_ITEM          
             15 PRINT_NEWLINE       

  6          16 LOAD_GLOBAL              1 (quux)
             19 PRINT_ITEM          
             20 PRINT_NEWLINE       
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE        
>>> 

看看baz(出现在foo()赋值的左侧)是如何成为唯一的LOAD_FAST变量的。

您可能需要探索名称空间的概念。在Python中,模块是全局数据的自然位置:

每个模块都有自己的专用符号表,该表被模块中定义的所有函数用作全局符号表。因此,模块的作者可以在模块中使用全局变量,而不用担心与用户的全局变量发生意外冲突。另一方面,如果你知道你在做什么,你可以用与引用它的函数相同的符号modname.itemname来触摸模块的全局变量。

这里描述了模块中全局变量的具体用法-如何在模块之间共享全局变量?,为完整起见,内容如下:

在单个程序中跨模块共享信息的规范方法是创建一个特殊的配置模块(通常称为config或cfg)。只需在应用程序的所有模块中导入配置模块;然后,模块变为可用的全局名称。因为每个模块只有一个实例,所以对模块对象所做的任何更改都会在任何地方反映出来。例如:

文件:config.py

x=0#“x”配置设置的默认值

文件:mod.py

import config
config.x = 1

文件:main.py

import config
import mod
print config.x

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

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

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默认创建本地变量,并使用全局关键字显式选择其他行为。

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

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

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

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