[Solved] Read and write a variable in module A from module B


When you execute your moduleA you’re running it as a script – essentially a module with the name of __main__, not as a ‘normal’ module, and that’s how it gets loaded. If you go and look through sys.modules as soon as you start it (before you import moduleB) you ain’t gonna find your moduleA there but you’ll find module __main__ (which will soon enough hold a variable with value 10).

Then when you import your moduleB, it imports moduleA – Python tries to find the loaded moduleA but there isn’t any, so it tries to load it from the disk and voila! it gets loaded, but this time as moduleA. Python then looks for moduleB that is imported from moduleA, and since it’s already there it doesn’t make any fuss about it despite the cyclic dependency (and if you have something like that in your code – you’re doing it wrong).

Anyway, since it’s now loaded as moduleA, its if __name__ == "__main__": block evaluates to false so it doesn’t cause any additional fuss. moduleB proceeds with its execution, but it also doesn’t match its if __name__ == "__main__": block so it just gets loaded and sits there.

Now we’re back in our __main__ representation of moduleA – its if __name__ == "__main__": block evaluates to true, so it calls its main() function, which in turn calls moduleB‘s main() function, which then changes the variable value but in moduleA, not in __main__. So, now when it gets back to __main__ and it tries to read its own variable value it gets the unchanged version of 10. But if you were to print out: print(getattr(sys.modules["moduleA"], "variable")) you’d see that your moduleB indeed changed the variable of moduleA.

If you really want to force the change in main, try having your moduleB like:

import sys

def main():
    moduleA = sys.modules["__main__"]  # this is the executing `moduleA` in your case
    print("From moduleB, variable =", moduleA.variable, " before change.")
    moduleA.variable = 20
    print("From moduleB, variable =", moduleA.variable, " after change.")

if __name__ == "__main__":
    main()

Which will, running your test case from moduleA, print out:

('From moduleA, variable=", 10, " before change.')
('From moduleB, variable=", 10, " before change.')
('From moduleB, variable=", 20, " after change.')
('From moduleA, variable=", 20, " after change.')

That’s what’s going on here, and the same is happening with your static vars example – you’re consistently targeting the ‘wrong’ module form your moduleB. Either way, please do not do this in any sort of a production code or any situation where other developers might end up having to mess with your code – cyclic redundancies are the bane of all things nice.

2

solved Read and write a variable in module A from module B