Python 导入错误。循环引用

Python 导入错误。循环引用,python,hierarchy,importerror,Python,Hierarchy,Importerror,我有一个这样的包裹 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

我有一个这样的包裹

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
from moduleB import foo
在moduleA中,我正在导入

from moduleA import bar
from moduleB import foo
我越来越害怕了

ImportError: cannot import name foo
这里有什么问题?为了避免这个问题,我应该怎么做?我应该在\u init\u.py pf包中写什么,子包1,子包2

_子包1的初始化.py

from moduleA import *
from moduleB import *
from moudleC import *
from moudleD import *
_子包2的初始化.py

from moduleX import *
from moduleY import *
from moduleZ import *
_包的初始化.py

from subpackage1 import *
from subpackage2 import *
我的\u init\u.py文件有问题吗

编辑: 我换了进口货

模B

from .moduleA import bar
def Bar():
    def __init__(self):
        self.foo = Foo()
        self.val = 10
        .
        .

from .moduleB import foo
def Foo():
    def __init__(self):
        self.bar = Bar()
        self.val = 5
        .
        .   
不过,我还是遇到了同样的导入错误

ImportError: cannot import name foo
编辑

模B

from .moduleA import bar
def Bar():
    def __init__(self):
        self.foo = Foo()
        self.val = 10
        .
        .

from .moduleB import foo
def Foo():
    def __init__(self):
        self.bar = Bar()
        self.val = 5
        .
        .   

我想这样做。我坚持将这两个类保存在不同的文件中。我应该如何导入?

实际上,循环导入似乎存在问题

您的moduleB显示“来自moduleA导入栏”,它尝试加载moduleA,但在moduleA中遇到的第一件事是“来自moduleB导入foo”,它将其发送回moduleB。这里有一个不可解的循环递归

通常(但不总是)循环导入是一个指标,您需要重新思考或重新设计您的工作方式。然而,有一些可能的解决办法

一种是将import语句移动到python文件的底部(假设您在另一个函数中使用foo或bar,因此在加载文件时不会立即调用它)

e、 g

另一种选择是将import语句放在一个称为“lazy import”模式的函数中:

至于你关于
\uuuu init\uuuuu.py
文件的问题。我看你没有理由不让它们空着。空的
\uuuu init\uuuu.py
文件只是告诉python“这个目录是一个python包”,并允许导入

通常,您的包目录中会有一个文件,该文件通过导入和利用子包中的模块来“运行”您的程序。因此,假设存在这样的文件(例如package/main.py),您的导入将如下所示,其中只有空的
\uuuuu init\uuuuu.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 
您在上面所做的基本上是获取每个子包中所有模块的所有函数和属性,并使它们直接在子包上可用,就像它们是子包的函数和属性一样(因此您可以
导入子包1
并调用
子包1.bar()
子包.foo()
而不是
subpackage.moduleA.bar()
等),但我没有得到这样的印象,这是你试图做的,当然,在这种情况下,可能没有理由这样做


如果您需要在subpackage1中的模块中使用subpackage2中的某些内容,请参阅或通过google了解如何将目录添加到python路径

这与层次结构无关,而是与循环引用有关。您不能告诉文件A导入文件B,文件B导入文件A-因为它们相互依赖,所以无法解析圆


要么重新构造文件,使它们不需要相互导入—记住Python不是Java,一个文件中可以有多个类—要么将其中一个导入移动到一个函数中,这样它就不必在导入时执行。

我想你指的是类Foo和类Bar?不管是哪种方式,我都会在我的答案中展示一些如何做到这一点的例子。ModuleB或ModuleA中只有一个必须遵循我展示的模式之一,另一个仍然可以在顶部执行。还有其他问题吗?谢谢。它起作用了。但我得到了RuntimeError:超过了最大递归深度。我从酒吧打电话给福,从福打电话给酒吧。我会调查的,不客气。听起来好像有一些无限递归在进行,如果每次初始化它们时都要创建一个新的递归,这是意料之中的。你需要重新思考你的设计。也许在实例化Bar()时,您可以从Foo()传入一个引用。这样的话,酒吧就有了一个foo。例如,在Bar:(uu init_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuoself,foo):self