Circular (or cyclic) imports in Python Circular (or cyclic) imports in Python python python

Circular (or cyclic) imports in Python


If you do import foo (inside bar.py) and import bar (inside foo.py), it will work fine. By the time anything actually runs, both modules will be fully loaded and will have references to each other.

The problem is when instead you do from foo import abc (inside bar.py) and from bar import xyz (inside foo.py). Because now each module requires the other module to already be imported (so that the name we are importing exists) before it can be imported.


There was a really good discussion on this over at comp.lang.python last year. It answers your question pretty thoroughly.

Imports are pretty straightforward really. Just remember the following:

'import' and 'from xxx import yyy' are executable statements. They execute when the running program reaches that line.

If a module is not in sys.modules, then an import creates the new module entry in sys.modules and then executes the code in the module. It does not return control to the calling module until the execution has completed.

If a module does exist in sys.modules then an import simply returns that module whether or not it has completed executing. That is the reason why cyclic imports may return modules which appear to be partly empty.

Finally, the executing script runs in a module named __main__, importing the script under its own name will create a new module unrelated to __main__.

Take that lot together and you shouldn't get any surprises when importing modules.


Cyclic imports terminate, but you need to be careful not to use the cyclically-imported modules during module initialization.

Consider the following files:

a.py:

print "a in"import sysprint "b imported: %s" % ("b" in sys.modules, )import bprint "a out"

b.py:

print "b in"import aprint "b out"x = 3

If you execute a.py, you'll get the following:

$ python a.pya inb imported: Falseb ina inb imported: Truea outb outa out

On the second import of b.py (in the second a in), the Python interpreter does not import b again, because it already exists in the module dict.

If you try to access b.x from a during module initialization, you will get an AttributeError.

Append the following line to a.py:

print b.x

Then, the output is:

$ python a.pya in                    b imported: Falseb ina inb imported: Truea outTraceback (most recent call last):  File "a.py", line 4, in <module>    import b  File "/home/shlomme/tmp/x/b.py", line 2, in <module>    import a File "/home/shlomme/tmp/x/a.py", line 7, in <module>    print b.xAttributeError: 'module' object has no attribute 'x'

This is because modules are executed on import and at the time b.x is accessed, the line x = 3 has not be executed yet, which will only happen after b out.


matomo