You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何重复导入Python模块全局变量会生效?导入机制疑问解析

Python重复导入变量为何会更新值?

问题场景

运行main.py的输出如下:

$ python main.py
var = 10
(main)       "var" in globals() = True
(change_var) "var" in globals() = True
sub1_globals == main_globals = False
var = 10
sub1_globals["var"] = 20
main_globals["var"] = 10
var is main_globals["var"] = True
var is sub1_globals["var"] = False
reimport var = 20

调用change_var()修改了sub1模块中的var为20,但主模块main里的var仍为10。但当在main中再次执行from sub1 import var后,main里的var变成了20。按认知Python模块仅可导入一次,为何重复导入会让变量值更新?

涉及代码

sub1.py

var = 10
def change_var():
    print(f'(change_var) {"var" in globals() = }')
    global var
    var = 20
    return globals()

main.py

from sub1 import var, change_var

if __name__ == "__main__":
    print(f'{var = }')
    print(f'(main)       {"var" in globals() = }')
    sub1_globals = change_var()
    main_globals = globals()
    print(f'{sub1_globals == main_globals = }')
    print(f'{var = }')
    print(f'{sub1_globals["var"] = }')
    print(f'{main_globals["var"] = }')
    print(f'{var is main_globals["var"] = }')
    print(f'{var is sub1_globals["var"] = }')
    from sub1 import var
    print(f"reimport {var = }")

原因解释

你对「模块仅导入一次」的认知是对的,但from ... import ...的行为和你想的不一样:

  • 模块确实只会被加载一次,重复执行import或from ... import ...不会重新运行模块的代码。
  • 但from sub1 import var的本质是:从已经加载好的sub1模块对象中,取出当前var的引用,然后覆盖当前命名空间(main的全局命名空间)里的var变量。

具体过程拆解:

  1. 第一次导入:from sub1 import var把sub1模块中var的引用(指向整数10)复制到main的全局命名空间,此时main的var和sub1的var都指向10。
  2. 调用change_var():函数里用global var声明操作sub1的全局var,然后将其重新赋值为20——因为整数是不可变类型,这相当于让sub1的var指向了一个新的整数对象20,但main的var还是指向原来的10,所以此时输出var=10。
  3. 再次导入:from sub1 import var不会重新加载sub1.py,但会去sub1模块的全局命名空间里取当前的var(也就是指向20的引用),然后把main全局命名空间里的var替换成这个新引用,所以之后输出var=20。

如果想避免这种覆盖,可以直接导入模块,通过sub1.var访问,而不是单独导入变量:这样每次访问的都是sub1模块里的当前值,也不会被覆盖。

内容的提问来源于stack exchange,提问作者Drunkwcodes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 14:00:31