如何在Python多个文件间设置可同步更新的共享全局变量
问题根因
你当前修改不生效是Python的模块导入机制导致的:使用from common import *导入device变量时,相当于在当前模块的命名空间创建了一个独立的同名副本,你在train.py里修改的只是train模块本地的device变量,不会影响common模块本身的属性,也不会同步到eval.py里导入的device副本。
提示:尽量不要用Python内置函数名
eval作为自定义函数名,避免命名冲突导致未知问题,以下示例保留你原有的命名方便对照。
方案1:给eval函数传参(最推荐,无全局依赖)
这个方案完全不需要依赖全局变量,模块间耦合度最低,符合Python的最佳实践。
修改代码:
eval.py修改如下:
def eval(device): print(device)
train.py修改如下:
from eval import eval import click @click.command() @click.argument("dev", type=str) def train(dev): device = dev # 调用时直接传入参数 eval(device) if __name__ == "__main__": train()
方案2:直接修改common模块的属性(改动最小,符合你的导入限制要求)
如果你不想修改eval函数的签名,只需要放弃from import单独导入变量的方式,直接操作common模块的属性即可,所有引用common模块属性的地方都会自动同步最新值。
修改代码:
common.py无需修改eval.py修改如下:
# 导入整个common模块,不要导入单独的变量 import common def eval(): # 读取common模块的属性 print(common.device)
train.py修改如下:
# 导入整个common模块,不要导入单独的变量 import common from eval import eval import click @click.command() @click.argument("dev", type=str) def train(dev): # 直接修改common模块的属性,所有导入common的地方都能读到最新值 common.device = dev eval() if __name__ == "__main__": train()
方案3:用可变容器存储全局配置
如果一定要用from import的导入方式,可以把配置放在字典、类实例这类可变对象里,修改可变对象的内部属性时,所有引用该对象的地方都会同步更新。
修改代码:
common.py修改如下:
# 用字典存储配置,字典是可变对象 config = { "device": "cpu" }
eval.py修改如下:
from common import config def eval(): print(config["device"])
train.py修改如下:
from common import config from eval import eval import click @click.command() @click.argument("dev", type=str) def train(dev): # 修改字典的内部值,所有引用config的地方都能读到最新值 config["device"] = dev eval() if __name__ == "__main__": train()
内容的提问来源于stack exchange,提问作者Ahmad
相关产品推荐
相关产品推荐

