使用ImportError从父目录导入失败

时间:2012-12-11 09:21:50

标签: python

我正忙于在python中开发应用程序,我的应用程序结构如下

main.py
pr/
    core/
        __init__.py
        predictor.py
    gui/
        predictor/
            __init__.py
            predict_panel.py
        __init__.py
        pr_app.py
    __init__.py

我使用main.py

启动应用程序

pr_app.py里面我有

class PrApp(wx.App):
    PREDICTOR = Predictor()

predict_panel.py里面我可以成功地做到

from pr.core.predictor import Predictor

但由于某种原因,我无法做到

from pr.gui.pr_app import PrApp

我收到了

ImportError: cannot import name PrApp

从python中的父目录导入时是否存在某种问题,或者我错过了什么?

3 个答案:

答案 0 :(得分:2)

我尝试了这个并创建了一个类似于你的树,但在__init__.py目录中添加了pr。如果没有__init__.py您的from pr.core.predictor import Predictor会失败,所以我认为您已经失败了,但忘了在您的问题中写下来。

我无法解决你所做的失败,它对我来说很好。我可以按照我的预期从predict_panel.py进行两次导入。

但是,如果我来自pr_app.py导入predict_panel,则predict_panel.py PrApp的导入将失败。这是因为我有一个循环导入。您尝试在导入predict_panel期间从PrApp导出PrApp,并尝试在导入PrApp期间导入predict_panel。这将创建无限的导入递归,因此不允许。

解决此问题的最佳方法是重新组织代码,这样您就不必进行循环导入。如果PrApp导入predict_panel,为什么predict_panel需要PrApp?这是设计有缺陷的标志。

然而,解决它的最快方法是将其中一个导入从模块顶部移动到调用它的函数/方法中。这是不好的做法,但它会很快解决你的问题。

答案 1 :(得分:0)

  

我使用main.py

启动应用程序

通过这样做,您可以正确地将pr/文件夹设为一个包,因此该包中的交叉引用导入应该有效。因此,pr.gui.pr_app import PrAppfrom ..pr_app import PrApp都应该有效。

我认为您的问题是您没有将pr作为真正的包裹。尝试在那里添加__init__.py,它应该可以正常工作。

答案 2 :(得分:-1)

无法从父目录导入的原因是每个脚本都将自己视为顶级导入树。它所看到的唯一其他事情是sys.path。所以据我所知,从上面导入的唯一机会是将父目录添加到路径中(绝对不是相对的)。

将它放在文件的顶部:

import sys
import os
import inspect

#enable imports from dir above
sys.path.append(os.path.abspath(
    os.path.dirname(inspect.getfile(inspect.currentframe()))+"/.."))