为何直接运行Python脚本时全局变量m1更新后不生效?
这个现象的核心是Python脚本直接运行和作为模块导入时的模块命名空间差异,导致全局变量出现两个独立实例。
具体拆解:
当你直接运行
collect_finetuning.py时,Python会把这个文件当作__main__模块加载,此时脚本里的全局变量m1属于__main__命名空间。
如果你的脚本内部存在导入自身的代码(比如import collect_finetuning或相对导入),Python会再次加载这个文件,这次会创建一个名为collect_finetuning的独立模块,同时生成一个全新的m1变量实例。
要是你的函数是通过模块引用(比如collect_finetuning.m1)来修改变量,那实际修改的是collect_finetuning模块里的m1,而main()函数所在的__main__模块里的m1根本没被改动,所以回到main()里看到的还是初始的空列表。当你从另一个脚本通过
from scripts.collect_finetuning import main调用时,collect_finetuning.py会被加载为scripts.collect_finetuning模块。
此时脚本内部的自身导入会直接引用已经加载的模块实例,不会重新加载,函数修改的m1和main()访问的m1是同一个变量,所以修改后的值能被保留。
另外还有一种小概率情况:如果你的函数修改m1时没有用global声明就直接赋值(比如m1 = [1,2]),那函数里的m1会被当成局部变量,不会修改全局的m1。但这种情况在导入调用时也应该无效,所以更大概率是模块重复加载导致的多实例问题。
内容的提问来源于stack exchange,提问作者Yelnar Blats

