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