Three python modules calling each other
I am working on a project where I have three python modules ( a.py
, b.py
and c.py
).
A module a
calls a module b
, a module b
calls a module c
, and a module c
calls a module a
. But this behavior is very fast when it works.
Here are my three modules:
a.py
print('module a')
def a() :
print('inside a')
return True
import b
b.b()
b.py
print('module b')
def b() :
print('inside b')
return True
import c
c.c()
c.py
print('module c')
def c() :
print('inside c')
return True
import a
a.a()
When I run a.py
, the observable result is:
module a
module b
module c
module a
inside b
inside a
inside c
inside b
While the expected behavior is:
module a
module b
module c
module a
inside b
Why is this happening? Is there an alternative way for such an implementation?
source to share
It has to do with stack frames and function calls and imports.
Start with start a.py .
'module a'
The first thing that happens is import b
:
'module b'
Inside b, c.py is imported :
'module c'
Module c imports a and we get:
'module a'
b was already imported from running a.py , so this call import b
is passed (we are not reimporting > b.py ). We then see the effects of invoking the following statement: b.b()
inside b
And we go back to the c.py frame where we call a.a()
:
inside a
c.py has completed its course; then go back to b.py where we left off (just after import) and call c.c()
:
inside c
B.py is now complete . Finally, we go back to the a.py frame from which we start the program and call b.b()
:
inside b
Hope this helps explain this behavior. Here's an example of how you could fix this problem and get the desired result:
a.py
print("module a")
import b
def main():
b.b()
def a():
print("inside a")
if __name__ == "__main__":
main()
b.py
print("module b")
import c
def main():
c.c()
def b():
print("inside b")
if __name__ == "__main__":
main()
c.py
print("module c")
import a
def main():
a.a()
def c():
print("inside c")
if __name__ == "__main__":
main()
Here is a link to explain what's going on with the call if __name__ == "__main__": main()
. Basically, it will only run the function main()
for each script if it is the script that is created and run in the first place. This way you will get the desired output:
module a
module b
module c
module a
inside b
source to share
I think the key misunderstanding is that you don't expect all modules to work after importing them, but they do. They interrupted in the middle of the script to do another import, but they will come back to finish the commands.
So what's going on: (I am removing the function declarations, just for clarity)
print('module a')
import b
>>> importing b
print('module b')
import c
>>> importing c
print('module c')
import a
>>> importing a
print('module a')
import b
>>> Doesn't reimport b
b.b()
a.a()
c.c()
b.b()
So, just show the order of the commands without imports and nesting:
print('module a')
print('module b')
print('module c')
print('module a')
b.b()
a.a()
c.c()
b.b()
And that matches your actual output.
source to share