简体   繁体   English

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

[英]Unable to see changes to a global variable from a different Python module

Consider the following Python application of two files, namely app.py :考虑以下两个文件的 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()

and other.py :other.py

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

I would like to make MY_DICT from app.py visible in other.py .我想让MY_DICT中的app.pyother.py中可见。 It is visible, but I cannot change it.它是可见的,但我无法更改它。 Here is the output if I run ./app.py with Python 3.8.0:这是 output 如果我用 Python 3.8.0 运行./app.py

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}

Not only MY_DICT is back to its initial state when inspected from other.py , it's back to the changed state when I return to main.py .当从other.py检查时,不仅MY_DICT回到了它最初的 state ,当我回到 main.py 时,它也回到了改变后的main.py What is happening here and how do I make it the a real global variable?这里发生了什么,我如何使它成为一个真正的全局变量?

I've already read this question and ensured that I do re-import MY_DICT in check_dict .我已经读过这个问题并确保我在check_dict中重新导入MY_DICT

Solution : don't do that.解决方案:不要那样做。 Do not import the entry point Python script as a module.不要将入口点 Python 脚本作为模块导入。 Create a separate small file which is never imported by anyone else and is intended to be run from the shell.创建一个单独的小文件,该文件永远不会被任何其他人导入,并且旨在从 shell 运行。

When you run the app as ./app.py Python actually loads your app.py as a module named __main__ .当您以 ./app.py 运行应用程序时, ./app.py实际上将您的app.py作为名为__main__的模块加载。 But your other.py says import app , so it imports a separate module named app , which is only coincidentally loaded from the same source file app.py .但是你的other.pyimport app ,所以它导入了一个名为app的单独模块,它只是巧合地从同一个源文件app.py

Now you have two instances of app.py loaded in your program, each one having a separate MY_DICT .现在您的程序中加载了两个app.py实例,每个实例都有一个单独的MY_DICT Your __main__ module sees its own sys.modules['__main__'].MY_DICT , but other module accesses sys.modules['a'].MY_DICT .您的__main__模块看到自己的sys.modules['__main__'].MY_DICT ,但other模块访问sys.modules['a'].MY_DICT You can check this by printing id(MY_DICT) in both main() and check_dict() : they are different.您可以通过在main()check_dict()中打印id(MY_DICT)来检查这一点:它们是不同的。 See more details here . 在此处查看更多详细信息。

Technically, you can import __main__ as app in other.py .从技术上讲,您可以import __main__ as appother.py中。 However, that will break the moment someone tries to use other.py in any other way which does not involve starting ./app.py .但是,当有人试图以任何其他不涉及启动./app.py的方式使用other.py时,这将中断。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM