Python3.6+跨文件共享全局变量修改后退出回调取值异常如何解决
问题原因
Python导入变量时,若使用from module import var的写法,本质是在当前模块的命名空间创建一个本地变量副本,指向module.var当时引用的对象。
你场景中的test是字符串类型,属于不可变对象,当你在run.py中修改globals.test时,实际是给mypack.globals模块的test属性重新绑定了新的字符串对象'PASS',但stuff.py中已经导入的本地test变量仍然指向原来的'FAIL'对象,因此退出回调读到的是旧值。
解决方案
方案1(推荐):导入全局变量所属模块,而非直接导入变量
始终通过模块属性访问全局变量,避免本地副本的产生,只需修改stuff.py代码即可:
import atexit # 导入整个globals模块,不单独导入test变量 from . import globals as g def cya(): # 读取模块属性获取最新值 print ("EXIT: test = " + g.test) atexit.register(cya) def hi(): print('HI')
修改后执行代码,退出回调将正常读到'PASS'的结果。
方案2:将全局变量封装到可变容器中
如果需要批量管理全局变量,可以将变量存入字典、列表、自定义类实例等可变容器中,修改容器内部的内容不会改变容器本身的引用,所有导入该容器的位置都能读到最新值:
- 修改globals.py代码:
# 用字典存储全局变量 global_conf = { "test": "FAIL" }
- 修改stuff.py代码:
import atexit from .globals import global_conf def cya(): print ("EXIT: test = " + global_conf['test']) atexit.register(cya) def hi(): print('HI')
- 修改run.py的变量修改逻辑:
import mypack import mypack.globals as globals mypack.hi() # 仅修改容器内的属性,不触发引用重绑定 globals.global_conf['test'] = 'PASS' print ("MAIN: test = " + globals.global_conf['test'])
内容的提问来源于stack exchange,提问作者backstreetrover
相关产品推荐
相关产品推荐

