我有这样的包
package/
__init__.py
subpackage1/
__init__.py
moduleA.py
moduleB.py
moduleC.py
moduleD.py
subpackage2/
__init__.py
moduleX.py
moduleY.py
moduleZ.py
在moduleB.py中,我正在导入
from moduleA import bar
在moduleA中,我正在导入
from moduleB import foo
我收到了ImportError。
ImportError: cannot import name foo
这可能是什么问题?为了避免这个问题,我该怎么办?我应该在 _ init _ .py pf包,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 *
我的 _ init _ .py文件有问题吗?
修改: 我已经改变了进口
moduleB
from .moduleA import bar
moduleA
from .moduleB import foo
但是,我收到了相同的导入错误。
ImportError: cannot import name foo
修改:
moduleB
def Bar():
def __init__(self):
self.foo = Foo()
self.val = 10
.
.
moduleA
def Foo():
def __init__(self):
self.bar = Bar()
self.val = 5
.
.
我想这样做。我坚持要将这两个类保存在不同的文件中。我应该如何导入?
答案 0 :(得分:8)
实际上这似乎是循环导入的问题。
你的moduleB说"来自moduleA导入栏",它试图加载moduleA,但它在moduleA中遇到的第一件事是"来自moduleB import foo",它将它发送回moduleB。所以你在那里有一个无法解决的循环递归。
通常(但并非总是)循环导入是指示您需要重新思考或重新设计您的工作方式。但是,有一些可能的解决方法。
一种方法是将import语句移动到python文件的底部(假设您在另一个函数中使用了foo或bar,因此在文件加载时不会立即调用它)
e.g。
#ModuleB.py
class Bar(object):
def __init__(self):
self.foo = Foo()
self.val = 10
.
.
# at bottom of file
from moduleA import Foo
另一种方法是将import语句放在一个函数中,称为" lazy import"图案:
#ModuleB.py
class Bar(object):
def __init__(self):
from moduleA import Foo
self.foo = Foo()
self.val = 10
关于__init__.py
文件的问题。我认为你没有理由不把它们留空。空的__init__.py
文件只是告诉python"这个目录是一个python包"并允许进口。
通常,您的包目录中会有一个文件"运行"通过导入和利用子包中的模块来实现您的程序。因此,假设存在这样的文件(例如,package / main.py),您的导入将如下所示,只有空__init__.py
个文件。
#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
您上面所做的基本上是获取每个子包中所有模块的所有功能和属性,并使它们直接在子包上可用,就好像它们是子包的功能和属性一样(所以您可以import subpackage1
并致电subpackage1.bar()
和subpackage.foo()
而不是subpackage.moduleA.bar()
等,但我不会给您留下您想要做的事情的印象,必然,在这种情况下可能没有理由这样做。
如果您需要在subpackage1的模块中使用subpackage2中的内容,请参阅this question.的答案或谷歌如何将目录添加到您的python路径。
答案 1 :(得分:2)
这与层次结构无关,而是与循环引用有关。你不能告诉文件A导入文件B,文件B导入文件A - 因为它们相互依赖,所以圆圈无法解析。
要么重构你的文件,以便它们不需要互相导入 - 记住Python不是Java,你可以在一个文件中有多个类 - 或者将其中一个导入到一个函数中以便它不会必须在导入时执行。