问题
My team is working on huge project with Django. For sake of simplicity, here's plain Python to illustrate the problem (original problem has models and apps instead of classes (I know that both are classes) and packages (I know that both are packages as well)).
a.py:
from b import B1
class A1(object):
def __init__(self):
print "object A1"
class A2(object):
def __init__(self):
print "object A2"
A1()
B1()
b.py:
from a import A2
class B1(object):
def __init__(self):
print "object B1"
A2()
When a.py is called, it tries to import B1 from b package which, on the other hand, tries to import A2 from a package and then, from start, that repeats forever. Python says:
[dagrevis@localhost recursion]$ python2 a.py
Traceback (most recent call last):
File "a.py", line 1, in <module>
from b import B1
File "/home/dagrevis/Python/recursion/b.py", line 1, in <module>
from a import A2
File "/home/dagrevis/Python/recursion/a.py", line 1, in <module>
from b import B1
ImportError: cannot import name B1
One of the solutions would be to have one file per object. Something like C++ or Java has. Then I remembered what Guido said about Python: “Don't write Java (or C++, or Javascript, ...) in Python.“. Are there more Pythonic way to deal with this problem?
Thanks in any advice!
回答1:
Your use-case is not "solvable". You can turn the ImportError
into an AttributeError
importing the module a
(and b
) instead of importing the objects, but this does not change the fact that you wont be able to use these modules.
The problem is that your module a
requires to completely execute b
before being imported, but also b
requries a
to be completely executed before being imported.
This is simply impossible to solve, and it's a clear symptom that a refactoring is needed: your a
and b
modules should be a single module(or you may want to do some deeper refactoring).
edit: actually you may be able to solve this, even though I think it's quite ugly to do, putting the imports at the end of the file, when they are required. But I think this would be just a patch for some bigger problem.
回答2:
Your example is overly simplified -- it does not explain why the cyclical import is necessary. But anyway, here is one way to refactor it to runnable code:
a.py:
class A1(object):
def __init__(self):
print "object A1"
class A2(object):
def __init__(self):
print "object A2"
b.py:
class B1(object):
def __init__(self):
print "object B1"
c.py:
from a import A1, A2
from b import B1
A1()
A2()
B1()
来源:https://stackoverflow.com/questions/12474374/infinite-loop-with-python-imports-looking-for-pythonic-way