协慌网

登录 贡献 社区

在函数中使用全局变量

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

如果我在一个函数中创建一个全局变量,我如何在另一个函数中使用该全局变量?我是否需要将全局变量存储在需要访问的函数的局部变量中?

答案

您可以通过声明为使用其他功能的全局变量, global在分配给它的每个功能:

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

我想它的原因是,由于全局变量是如此危险,Python 希望通过明确要求global关键字确保你真正知道你正在玩的是什么。

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

如果我正确理解您的情况,您所看到的是 Python 处理本地(函数)和全局(模块)命名空间的结果。

假设你有一个这样的模块:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

你可能希望这打印 42,但它打印 5. 如前所述,如果你向func1()添加一个 ' global ' 声明,那么func2()将打印 42。

def func1():
    global myGlobal
    myGlobal = 42

这里发生的是 Python 假定在函数内的任何位置分配的任何名称都是该函数的本地名称,除非另有明确说明。如果它只是从名称读取 ,并且名称在本地不存在,它将尝试在任何包含范围中查找名称(例如模块的全局范围)。

因此,当您为名称myGlobal指定 42 时,Python 会创建一个局部变量,该变量会myGlobal的全局变量。当func1()返回时,本地超出范围并被垃圾收集 ; 同时, func2()除了(未修改的)全局名称之外永远不会看到任何其他内容。请注意,此命名空间决定发生在编译时,而不是在运行时 - 如果您在分配给它之前在func1()读取myGlobal的值, myGlobal得到UnboundLocalError ,因为 Python 已经确定它必须是一个局部变量,但它还没有任何与之相关的值。但是通过使用 ' global ' 语句,你告诉 Python 它应该在其他地方查找名称,而不是在本地分配它。

(我相信这种行为很大程度上是由于本地命名空间的优化 - 没有这种行为,每次在函数内部分配新名称时,Python 的 VM 都需要执行至少三次名称查找(以确保名称没有 ' t 已经存在于模块 / 内置级别),这将显着减慢非常常见的操作。)

您可能想要探索命名空间的概念。在 Python 中, 模块全局数据的自然场所:

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

这里描述了全局模块的特定用法 - 如何在模块间共享全局变量 ,并且为了完整性,内容在此处共享:

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

文件:config.py

x = 0   # Default value of the 'x' configuration setting

文件:mod.py

import config
config.x = 1

文件:main.py

import config
import mod
print config.x