Cyclic imports

Carl Banks pavlovevidence at gmail.com
Fri Jun 27 07:04:32 EDT 2008


On Jun 27, 12:58 am, James <rent.lupin.r... at gmail.com> wrote:
> > # a.py
> > import b
> > # refer to b.b
>
> > # b.py
> > import a
> > # refer to a.a
>
> Thanks Dan, but that still doesn't work for me I'm afraid...
>
> I renamed the modules avoid name overloading -- a.py is now:
> import b
>
> class A():
>     print('b.b_mod:', b.b_mod)
>
> b is now defined, but b.b_mod isn't:
>   File "main.py", line 1, in <module>
>     from a import a_mod
>   File "/Users/james/tmp/python/a/a_mod.py", line 3, in <module>
>     class A():
>   File "/Users/james/tmp/python/a/a_mod.py", line 4, in A
>     print('b.b_mod:', b.b_mod)
> AttributeError: 'module' object has no attribute 'b_mod'
>
> I must be missing something here - I've tried adding the modules to
> __all__ in __init__.py but that didn't help either.


The above print statement runs at module import time, so you're seeing
something that might not be an issue in functioning code.

For instance, if you rewrite A like the following:

class A(object):
    def print_b(self):
        print('b.b_mod:', b.b_mod)

If you call the print_b method from outside the module (say, from
main.py), it should work.


What lessons did we learn here?

Be aware of the difference between code that runs at module import
time, and code that runs after the module is imported.

In code that runs after the module has been imported (basically
anything defined in a function that isn't called by code that runs at
module time), you can expect the variables defined in the imported
module to be available.

In code that runs at module import time, there is no such guarantee,
so you have to arrange your modules so that code that depends on
another module is run after the dependent module.  (One common time
where this happens is when subclassing a class from another module:
the module with the base class needs to run first.)

If you have circular imports involved, making sure the modules import
in a certain order can be quite hairy.  (Faced with this problem, I
found it necessary to write an import hook to pre-import certain
modules.)


Carl Banks



More information about the Python-list mailing list