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