Question

I switch program mode by modifying a global value in my main module.

The change is reflected in following function calls originating inside that module, but not when other modules call the same functions.

Is the main module using an old/external/duplicated value when function calls come from the outside?

main_module.py

import second_module

mode = 1

def print_mode():
  print 'Mode: ' + str(mode)

if __name__ == "__main__":
  print_mode()
  mode = 2
  print_mode()
  second_module.problem()

second_module.py

from main_module import print_mode

def problem():
  print_mode()

output

$ python main_module.py
Mode: 1
Mode: 2
Mode: 1
Was it helpful?

Solution

The file you supply at the command line is executed as a module named __main__ (the __name__ == '__main__' condition is is relying on this). Modules are generally only imported once, future imports give another reference to the same module name.

However, this mechanism is based on the module name. from main_module import print_mode looks for a module named main_module, but there is no such module yet, so the file is loaded again and a separate module called main_module is created. This entails executing the code from main_module.py again, which again initializes mode = 1, but does fails the aforementioned condition and hence doesn't do anything else (such as mode = 2).

So you end up with three modules: __main__, second_module, and main_module. __main__.mode == 2, but main_module.mode == 1, and second_module.print_mode is main_module.print_mode, so the print_mode call in second_module refers to main_module.mode which is 2.

The easy way out is not having any logic in __main__: Put your entry point in a function main() in main_module.py, then create a separate script which doesn't do anything other than importing main_module and calling main_module.main(). Alternatively, don't use globals ;-)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top