Back to results for “Scope”
Python › Modules & Packaging

How does Python resolve circular imports, and what strategies avoid the resulting ImportError?

Advanced

Answer

A circular import occurs when module A imports module B, and B (directly or indirectly) imports A, potentially trying to access a name in A before A has finished executing (since A is partially initialized in sys.modules during the circular import). Common fixes include: restructuring code to remove the cycle, moving the import inside a function (deferred/local import) so it happens after both modules are fully loaded, or importing the module itself rather than specific names from it (`import a` then `a.something` instead of `from a import something`).
# a.py
import b
def func_a():
    return b.func_b()

# b.py
def func_b():
    import a  # deferred import avoids circular ImportError at module load time
    return 'from b'
Real-world example Two tightly-coupled modules in a Django app (models.py and signals.py) resolve a circular import by moving one import inside a function body, deferring it until after both modules have fully loaded.

Common follow-ups: Why does moving an import inside a function fix the cycle?;How does restructuring shared code into a third module help?