无法看到来自不同 Python 模块的全局变量的更改

Unable to see changes to a global variable from a different Python module

考虑以下两个文件的Python应用,即app.py:

#!/usr/bin/env python3
import other


MY_DICT = {'initial': 10}


def main():
    print('before main:', MY_DICT)
    MY_DICT['foo'] = 20
    MY_DICT['bar'] = 30
    print('after changes:', MY_DICT)
    other.check_dict()
    print('back in main:', MY_DICT)


if __name__ == '__main__':
    main()

other.py:

def check_dict():
    from app import MY_DICT
    print('inside other:', MY_DICT)

我想让 app.py 中的 MY_DICTother.py 中可见。它是可见的,但我无法更改它。这是我 运行 ./app.py 和 Python 3.8.0:

的输出
before main: {'initial': 10}
after changes: {'initial': 10, 'foo': 20, 'bar': 30}
inside other: {'initial': 10}
back in main: {'initial': 10, 'foo': 20, 'bar': 30}

不仅 MY_DICTother.py 检查时回到了初始状态,当我 return 到 main.py 时,它也回到了更改后的状态。这里发生了什么,我如何使它成为一个真正的全局变量?

我已经阅读 this question 并确保我在 check_dict 中重新导入 MY_DICT

解决方法:不要那样做。不要将入口点 Python 脚本作为模块导入。创建一个单独的小文件,该文件永远不会被任何其他人导入,并且旨在成为 shell.

中的 运行

当您 运行 作为 ./app.py Python 的应用程序实际上将您的 app.py 作为名为 __main__ 的模块加载。但是你的 other.pyimport app,所以它导入了一个名为 app 的单独模块,它只是巧合地从同一个源文件 app.py.

加载

现在您的程序中加载了两个 app.py 实例,每个实例都有一个单独的 MY_DICT。您的 __main__ 模块看到它自己的 sys.modules['__main__'].MY_DICT,但 other 模块访问 sys.modules['a'].MY_DICT。您可以通过在 main()check_dict() 中打印 id(MY_DICT) 来检查这一点:它们是不同的。查看更多详细信息 here

从技术上讲,您可以在 other.pyimport __main__ as app。但是,当有人试图以任何其他不涉及启动 ./app.py.

的方式使用 other.py 时,这将中断