导入错误。通函参考

时间:2012-06-14 07:39:05

标签: 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中,我正在导入

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
        .
        .   

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

2 个答案:

答案 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,你可以在一个文件中有多个类 - 或者将其中一个导入到一个函数中以便它不会必须在导入时执行。