Python变量 - 跨模块的Discord

3

我通过修改主模块中的全局变量来切换程序模式。

这种更改会反映在源自该模块内部的函数调用中,但不会反映在其他模块调用同一函数时。

当函数调用来自外部时,主模块是否在使用旧的/外部的/重复的值?

main_module.py

import second_module

mode = 1

def print_mode():
  print 'Mode: ' + str(mode)

if __name__ == "__main__":
  print_mode()
  mode = 2
  print_mode()
  second_module.problem()

second_module.py

from main_module import print_mode

def problem():
  print_mode()

输出

$ python main_module.py
Mode: 1
Mode: 2
Mode: 1

global 关键字在此处无效,因为它位于模块范围。 - Eric
1个回答

2
在命令行提供的文件将作为名为__main__的模块执行(条件__name__ == '__main__'依赖于此)。模块通常只被导入一次,未来的导入会给同一个模块名称另一个引用。
然而,这种机制是基于模块名称的。from main_module import print_mode寻找名为main_module的模块,但此时并没有这样的模块,因此该文件再次加载并创建了一个名为main_module的独立模块。这意味着再次执行main_module.py中的代码,它再次初始化mode = 1,但不满足前述条件,因此不会执行其他任何操作(如mode = 2)。
因此,你最终得到三个模块:__main__second_modulemain_module__main__.mode == 2,但main_module.mode == 1second_module.print_mode is main_module.print_mode,因此second_module中的print_mode调用指向main_module.mode,其值为2。
简单的方法是不在__main__中放置任何逻辑:在main_module.py中将入口点放在函数main()中,然后创建一个单独的脚本,除了导入main_module和调用main_module.main()之外不做其他任何事情。或者,不要使用全局变量;-)

谢谢,问题解决了!以后会避免在其他地方使用__main__。尽管完全避免全局变量会更好,但我不知道如何维护程序的模式/状态。 - fivecode
1
另一种方法是在文件顶部添加 if __name__ == '__main__': import main_module; main_module.main() - Eric
听起来像是在导入__main__期间停止导入同一模块,然后继续。这样不会给我们三个模块吗? - fivecode
1
@fivecode 是的,你会得到三个模块,但避免了任何应用程序状态重复的问题。这适用于此处提到的所有方法。 - user395760

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接