问题
I have a package like this
package/
__init__.py
subpackage1/
__init__.py
moduleA.py
moduleB.py
moduleC.py
moduleD.py
subpackage2/
__init__.py
moduleX.py
moduleY.py
moduleZ.py
In moduleB.py, I am importing
from moduleA import bar
In moduleA, I am importing
from moduleB import foo
I am getting ImportError.
ImportError: cannot import name foo
What could be the problem here ? and to avoid this problem, what should I do ? and what should I write in _init_.py pf package, subpackage1, subpackage2 ?
_init_.py of subpackage1
from moduleA import *
from moduleB import *
from moudleC import *
from moudleD import *
_init_.py of subpackage2
from moduleX import *
from moduleY import *
from moduleZ import *
_init_.py of package
from subpackage1 import *
from subpackage2 import *
Is there some problem with my _init_.py files ?
EDIT: I have changed imports
moduleB
from .moduleA import bar
moduleA
from .moduleB import foo
Still, I am getting the same import error.
ImportError: cannot import name foo
EDIT:
moduleB
def Bar():
def __init__(self):
self.foo = Foo()
self.val = 10
.
.
moduleA
def Foo():
def __init__(self):
self.bar = Bar()
self.val = 5
.
.
I want to do this. And I insist on keeping both classes in different files. How should I import ?
回答1:
It actually appears to be a problem with circular imports.
Your moduleB says "from moduleA import bar", which tries to load moduleA, but the first thing it encounters in moduleA is "from moduleB import foo", which sends it back to moduleB. So you have an unresolvable bit of circular recursion there.
Typically (but not always) a circular import is an indicator that you need to rethink or re-architect how you're doing things. There are, however, a few possible work-arounds out there.
One is to move the import statement to the bottom of your python file (assuming you're using foo or bar inside of another function, so its not getting called instantly when the file loads)
e.g.
#ModuleB.py
class Bar(object):
def __init__(self):
self.foo = Foo()
self.val = 10
.
.
# at bottom of file
from moduleA import Foo
another alternative is to place the import statement inside a function, called the "lazy import" pattern:
#ModuleB.py
class Bar(object):
def __init__(self):
from moduleA import Foo
self.foo = Foo()
self.val = 10
As to your question about the __init__.py
files. I see no reason why you wouldn't leave them empty. The empty __init__.py
files simply tell python "this directory is a python package" and permit imports.
Typically you would have a file in your package directory that "runs" your program by importing and utilizing modules from the subpackages. So assuming such file (e.g., package/main.py) exists, your imports would look like the following, with just empty __init__.py
files.
#package/main.py
from subpackage1.moduleA import bar # you can now call bar() directly
from subpackage1 import moduleB # you can now call foo like: moduleB.foo()
from subpackage2.moduleX import jah
What you're doing above essentially takes all of the functions and attributes of all of the Modules in each subpackage and makes them available directly on the subpackage as if they were the subpackage's functions and attributes (so you could import subpackage1
and call subpackage1.bar()
and subpackage.foo()
instead of subpackage.moduleA.bar()
, etc.), but I don't get the impression thats what you were trying to do, necessarily, and there's probably no reason to do it in this case.
If you need to use something in subpackage2 in a module in subpackage1, see the answers to this question. Or google how to add directories to your python path.
回答2:
This isn't to do with hierarchy, it's to do with circular references. You can't tell file A to import file B, and file B to import file A - since they depend on each other, the circle can't be resolved.
Either restructure your files so that they don't need to import each other - remember Python is not Java, you can have more than one class in a file - or move one of the imports into a function so that it doesn't have to execute at import time.
来源:https://stackoverflow.com/questions/11028711/import-error-circular-references