This is an old copy of the Python FAQ. The information here may be outdated.

How can I have modules that mutually import each other?

Suppose you have the following modules:

File foo.py:

from bar import bar_var
foo_var=1

File bar.py:

from foo import foo_var
bar_var=2

If you import the foo module from your main program, you get the following traceback:

Traceback (most recent call last):
  File "program.py", line 14, in <module>
    import foo
  File "foo.py", line 1, in <module>
    from bar import bar_var
  File "bar.py", line 1, in <module>
    from foo import foo_var
ImportError: cannot import name foo_var

The problem is that the interpreter will do things in the following order:

  • The main program imports foo
  • Empty globals for foo are created
  • foo is compiled and starts executing
  • foo imports bar
  • Empty globals for bar are created
  • bar is compiled and starts executing
  • bar imports foo (which is a no-op since there already is a module named foo)
  • bar.foo_var = foo.foo_var

The last step fails, because Python isn’t done with interpreting foo yet and the global symbol dictionary for foo is still empty.

The same thing happens when you use import foo, and then try to access foo.foo_var in global code.

There are a few ways to get around this problem:

The preferred way is simply to avoid recursive use of from-import, placing all code inside functions. Initializations of global variables and class variables should use constants and built-in or locally defined functions only. This means everything from an imported module is referenced as <module>.<name>.

Another way is to do things in the following order in each module:

  • exports (globals, functions, and classes that don’t need imported base classes)
  • import statements
  • active code (including globals that are initialized from imported values).

Yet another way is to move the import statements into the functions that are using the imported objects.

CATEGORY: programming

 

A Django site. rendered by a django application. hosted by webfaction.