简体   繁体   中英

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

Consider the following Python application of two files, namely 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 :

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 . It is visible, but I cannot change it. Here is the output if I run ./app.py with 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}

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 . 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 .

Solution : don't do that. Do not import the entry point Python script as a module. Create a separate small file which is never imported by anyone else and is intended to be run from the shell.

When you run the app as ./app.py Python actually loads your app.py as a module named __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 .

Now you have two instances of app.py loaded in your program, each one having a separate MY_DICT . Your __main__ module sees its own sys.modules['__main__'].MY_DICT , but other module accesses sys.modules['a'].MY_DICT . You can check this by printing id(MY_DICT) in both main() and check_dict() : they are different. See more details here .

Technically, you can import __main__ as app in other.py . However, that will break the moment someone tries to use other.py in any other way which does not involve starting ./app.py .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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