在函数中使用全局变量

2024-04-19 23:15:49 发布

您现在位置:Python中文网/ 问答频道 /正文


Tags: python
3条回答

如果我正确地理解了您的情况,那么您看到的是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假设任何分配给函数中任何地方的名称都是该函数的本地名称,除非另有明确说明。如果它只从一个名称中读取,而该名称在本地不存在,它将尝试在任何包含作用域(例如模块的全局作用域)中查找该名称。

因此,当您将42赋给名称myGlobal时,Python将创建一个局部变量,该变量将隐藏同名的全局变量。当func1()返回时,该局部超出了作用域并且是garbage-collected;同时,func2()除了(未修改的)全局名称之外,永远看不到任何其他内容。注意,这个名称空间决定发生在编译时,而不是运行时——如果要在分配给它之前读取myGlobal内部的func1()值,就会得到一个UnboundLocalError,因为Python已经决定它必须是一个局部变量,但它还没有任何相关联的值。但是,通过使用“global”语句,您可以告诉Python应该在其他地方查找名称,而不是在本地为其赋值。

(我相信这种行为主要是通过优化本地名称空间而产生的——如果没有这种行为,Python的VM将需要在每次为函数内部分配新名称时执行至少三次名称查找(以确保该名称在模块/内置级别上不存在),这将大大降低非常常见的操作。)

您可能想探索namespaces的概念。在Python中,module全局数据的自然位置:

Each module has its own private symbol table, which is used as the global symbol table by all functions defined in the module. Thus, the author of a module can use global variables in the module without worrying about accidental clashes with a user’s global variables. On the other hand, if you know what you are doing you can touch a module’s global variables with the same notation used to refer to its functions, modname.itemname.

这里描述了global-in-A-module的具体用法-How do I share global variables across modules?,为了完整起见,这里共享内容:

The canonical way to share information across modules within a single program is to create a special configuration module (often called config or cfg). Just import the configuration module in all modules of your application; the module then becomes available as a global name. Because there is only one instance of each module, any changes made to the module object get reflected everywhere. For example:

File: config.py

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

File: mod.py

import config
config.x = 1

File: main.py

import config
import mod
print config.x

您可以在其他函数中使用全局变量,方法是在分配给它的每个函数中将它声明为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关键字来确保您真正知道这是您正在玩的游戏。

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

相关问题 更多 >