Python circular importing?
Solution 1:
I think the answer by jpmc26, while by no means wrong, comes down too heavily on circular imports. They can work just fine, if you set them up correctly.
The easiest way to do so is to use import my_module
syntax, rather than from my_module import some_object
. The former will almost always work, even if my_module
included imports us back. The latter only works if my_object
is already defined in my_module
, which in a circular import may not be the case.
To be specific to your case: Try changing entities/post.py
to do import physics
and then refer to physics.PostBody
rather than just PostBody
directly. Similarly, change physics.py
to do import entities.post
and then use entities.post.Post
rather than just Post
.
Solution 2:
When you import a module (or a member of it) for the first time, the code inside the module is executed sequentially like any other code; e.g., it is not treated any differently that the body of a function. An import
is just a command like any other (assignment, a function call, def
, class
). Assuming your imports occur at the top of the script, then here's what's happening:
- When you try to import
World
fromworld
, theworld
script gets executed. - The
world
script importsField
, which causes theentities.field
script to get executed. - This process continues until you reach the
entities.post
script because you tried to importPost
- The
entities.post
script causesphysics
module to be executed because it tries to importPostBody
- Finally,
physics
tries to importPost
fromentities.post
- I'm not sure whether the
entities.post
module exists in memory yet, but it really doesn't matter. Either the module is not in memory, or the module doesn't yet have aPost
member because it hasn't finished executing to definePost
- Either way, an error occurs because
Post
is not there to be imported
So no, it's not "working further up in the call stack". This is a stack trace of where the error occurred, which means it errored out trying to import Post
in that class. You shouldn't use circular imports. At best, it has negligible benefit (typically, no benefit), and it causes problems like this. It burdens any developer maintaining it, forcing them to walk on egg shells to avoid breaking it. Refactor your module organization.