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.
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
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如何处理本地(函数)和全局(模块)名称空间的结果。
假设你有一个这样的模块:
你可能以为它会打印42,但它却打印5。如前所述,如果在
func1()
中添加“global
”声明,则func2()
将打印42。这里的情况是,Python假设任何分配给函数中任何地方的名称都是该函数的本地名称,除非另有明确说明。如果它只从一个名称中读取,而该名称在本地不存在,它将尝试在任何包含作用域(例如模块的全局作用域)中查找该名称。
因此,当您将42赋给名称
myGlobal
时,Python将创建一个局部变量,该变量将隐藏同名的全局变量。当func1()
返回时,该局部超出了作用域并且是garbage-collected;同时,func2()
除了(未修改的)全局名称之外,永远看不到任何其他内容。注意,这个名称空间决定发生在编译时,而不是运行时——如果要在分配给它之前读取myGlobal
内部的func1()
值,就会得到一个UnboundLocalError
,因为Python已经决定它必须是一个局部变量,但它还没有任何相关联的值。但是,通过使用“global
”语句,您可以告诉Python应该在其他地方查找名称,而不是在本地为其赋值。(我相信这种行为主要是通过优化本地名称空间而产生的——如果没有这种行为,Python的VM将需要在每次为函数内部分配新名称时执行至少三次名称查找(以确保该名称在模块/内置级别上不存在),这将大大降低非常常见的操作。)
您可能想探索namespaces的概念。在Python中,module是全局数据的自然位置:
这里描述了global-in-A-module的具体用法-How do I share global variables across modules?,为了完整起见,这里共享内容:
您可以在其他函数中使用全局变量,方法是在分配给它的每个函数中将它声明为
global
:我想其原因是,由于全局变量非常危险,Python希望通过显式地要求
global
关键字来确保您真正知道这是您正在玩的游戏。如果要跨模块共享全局变量,请参阅其他答案。
相关问题 更多 >
编程相关推荐