When two modules import each other there are a few things you need to keep in mind so everything is defined before it is needed.
First lets consider the mechanic of importing:
- when a module is imported for the first time an entry is added to
sys.modules
and the defining file starts executing (pausing the execution of the import-er)
- subsequent imports will simply use the entry in
sys.modules
- whether or not the file finished executing
So lets say module A
is loaded first, imports module B
which then imports module A
, when this happens execution is as follows:
A
is imported from something else for first time, A
is added to sys.modules
A
is executed up to importing B
B
is added to sys.modules
B
is executed:
- when it imports
A
the partially loaded module is used from sys.modules
B
runs completely before resuming
A
resumes executing, having access to the complete module B
*1 so from A import x
can only work if x
is defined in A
before import B
, just using import A
will give you the module object which is updated as the file executes, so while it may not have all the definitions right after import it will when the file has a chance to finish executing.
So the simplest way of solving this is to first not rely on the import for the execution of the module - meaning all the uses of the circular import is within def
blocks that are not called from the module level of execution.