导入错误。循环引用

2024-05-18 11:41:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样的包裹

package/
    __init__.py
    subpackage1/
        __init__.py
        moduleA.py
        moduleB.py
        moduleC.py
        moduleD.py
    subpackage2/
       __init__.py
       moduleX.py
       moduleY.py
       moduleZ.py

在模块B.py,我正在导入

^{pr2}$

正在导入moduleA

from moduleB import foo

我越来越紧张了。在

ImportError: cannot import name foo

有什么问题吗?为了避免这个问题,我该怎么办?我应该在initinit.py pf包,subpackage1,subpackage2中写什么呢?在

子包1的

from moduleA import *
from moduleB import *
from moudleC import *
from moudleD import *

子包2的

from moduleX import *
from moduleY import *
from moduleZ import *

包的初始化

from subpackage1 import *
from subpackage2 import *

我的init.py文件是否有问题?在

编辑: 我换了进口货

模数B

from .moduleA import bar

模数

from .moduleB import foo

不过,我还是得到了同样的导入错误。在

ImportError: cannot import name foo

编辑

模数B

def Bar():
    def __init__(self):
        self.foo = Foo()
        self.val = 10
        .
        .

模数

def Foo():
    def __init__(self):
        self.bar = Bar()
        self.val = 5
        .
        .   

我想这么做。我坚持把这两个班放在不同的档案里。我该如何导入?在


Tags: frompyimportselffooinitdef模数
2条回答

实际上,这似乎是循环进口的问题。在

您的moduleB显示“from moduleA import bar”,它试图加载moduleA,但在moduleA中遇到的第一件事是“from moduleB import foo”,它将它发送回moduleB。所以这里有一个不可解的循环递归。在

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

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

例如

#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”模式的函数中:

^{pr2}$

至于你关于__init__.py文件的问题。我看不出你为什么不让它们空着。空的__init__.py文件只告诉python“这个目录是一个python包”,并允许导入。在

通常,您的包目录中会有一个文件,通过导入和利用子包中的模块来“运行”程序。所以假设这样的文件(例如,包/主.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()和{},而不是{},等等),但我不认为这就是你想要做的,在这种情况下可能没有理由这么做。在

如果您需要在subpackage1的模块中使用subpackage2中的内容,请参阅this question.或google how to add directories to your python path。在

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

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

相关问题 更多 >