Circular imports (again)

Frank Millman frank at chagford.com
Tue Aug 10 05:13:06 EDT 2010


"Frank Millman" <frank at chagford.com> wrote in message 
news:i3ov9e$dug$1 at dough.gmane.org...
> Hi all
>
> I know the problems related to circular imports, and I know some of the 
> techniques to get around them. However, I find that I bump my head into 
> them from time to time, which means, I guess, that I have not fully 
> understood how to organise my code so that I avoid them in the first 
> place.
>
[...]
>
> So I think my main question is, is this a symptom of a flaw in my 
> approach, or is this something that all programmers bump into from time to 
> time?
>

Thanks for the replies. All good info, but it was Ethan that put me onto the 
right track.

I omitted to mention one thing originally, as I did not think it important, 
but it turns out to be crucial. My code is organised into three 'packages', 
not 'modules'.

To reproduce my situation, I did some tests with the following hierarchy -

top/
    a.py
    /bb
        __init__.py
        b.py
    /cc
        __init__.py
        c.py

a.py
----
import bb.b
import cc.c
bb.b.foo()
cc.c.foo()

b.py
----
import cc.c
def foo():
    print 'in b.foo, call c.bar'
    cc.c.bar()
def bar():
    print '  bar in b'

c.py
----
import bb.b
def foo():
    print 'in c.foo, call b.bar'
    bb.b.bar()
def bar():
    print '  bar in c'

If I run 'a.py', I get the correct result -

in b.foo, call c.bar
  bar in c
in c.foo, call b.bar
  bar in b

I changed 'a.py' -

a.py
----
from bb import b
from cc import c
b.foo()
c.foo()

It still worked.

Next I changed 'b.py' -

b.py
----
from cc import c
def foo():
    print 'in b.foo, call c.bar'
    c.bar()
def bar():
    print '  bar in b'

It still worked.

Then I changed 'c.py' -

c.py
----
from bb import b
def foo():
    print 'in b.foo, call c.bar'
    b.bar()
def bar():
    print '  bar in b'

Now I get the following traceback -
Traceback (most recent call last):
  File "F:\dd\a.py", line 1, in <module>
    from bb import b
  File "F:\dd\bb\b.py", line 1, in <module>
    from cc import c
  File "F:\dd\cc\c.py", line 1, in <module>
    from bb import b
ImportError: cannot import name b

Now that I understand this, I can work around my problem by using 
fully-qualified module names.

But it would be interesting to know the underlying reason for this 
behaviour.

I am using python 2.6.2.

Thanks for any insights.

Frank





More information about the Python-list mailing list