对如何从模块中的其他目录/父目录导入感到困惑(python 3)

Posted

技术标签:

【中文标题】对如何从模块中的其他目录/父目录导入感到困惑(python 3)【英文标题】:Confused about how to import from other directories / parent directories within module (python 3) 【发布时间】:2015-03-28 20:21:16 【问题描述】:

首先,我知道这里已经提出了许多与此相关的问题(This 和 This 似乎最相似)。我已经阅读了其中的一些内容,但我发现自己仍然对完成此任务的适当方法感到非常困惑。

我有一个正在做的项目是这样组织的:

--LabAnalysisModules
  |-- __init__.py
  |-- EphysTools
      |-- __init__.py
      |-- synaptics.py
      |-- utilities.py
  |-- PrairieAnalysis
      |-- pv_import.py
      |-- pxml_parse.py

--PVAnalysis
  |-- __init__.py
  |-- MainWindow.py
  |-- DataViewer.py
  |-- AnalysisWindows
      |-- __init__.py
      |-- AnalysisWidget.py

AnalysisWidget 继承自 DataViewer 中的 DataViewer 类。在尝试导入 DataViewer 时,我遇到了两点困惑。

    实际导入 DataViewer 的最合适方法是什么。我目前正在诉诸于在 AnalysisWidget 中包含 sys.path.append(os.path.abspath("../../PVAnalysis")),因为相对导入给了我 SystemError: Parent module '' not loaded, cannot perform relative import

    在 DataViewer 中,我有这个 try...except 块(在我的一些机器上 LabAnalysisModules 已永久添加到 python 路径中,而在其他机器上则没有)

    try:
        import PrairieAnalysis.pv_import as pvi
        import EphysTools.utilities as util
    except ImportError:
        import os
        sys.path.append(os.path.abspath('../LabAnalysisModules'))
        import PrairieAnalysis.pv_import as pvi
        import EphysTools.utilities as util
    

运行 DataViewer 本身工作正常,但我遇到另一个导入错误 import DataViewer from AnalysisWidget

ImportError: No module named 'PrairieAnalysis'

print(sys.path)添加到上面的except块中,这是导入DataViewer时添加到sys.path的内容:

E:\\Users\\Dan\\SkyDrive\\Documents\\Python\\PVAnalysis\\LabAnalysisModules'

这显然是不正确的。

我可以通过在 AnalysisWidget 中包含 sys.path.append('../../LabAnalysisModules') 来修复此导入错误,但这似乎是一个非常笨拙的修复

编辑 1

正如我在 cmets 中所说,最终 AnalysisWidget 将由 MainWindow 导入。同样,真的不清楚相对进口是如何工作的。获取:

    from .. import DataViewer
ValueError: attempted relative import beyond top-level package

归根结底,我想做的两件事是:

    能够简单地运行 AnalysisWidget.py(我知道通常不应该从模块中运行脚本,但是在创建 GUI 时我发现自己一直都在这样做)

    能够将 AnalysisWidget 导入 MainWindow。

如果我也清理一下我为 LabAnalysisModules 进行导入的方式,那就太好了。

【问题讨论】:

你如何调用AnalysisWidget?直接,还是用-m 切换到Python? 上面报告的 SystemError 只是尝试在 python shell 中导入 AnalysisWidget。我曾尝试使用 -m 开关,但我似乎没有正确地做某事,因为我在查找...等规范时出现错误 最终,AnalysisWidget 将由 MainWindow 导入。 from .. import DataViewer: 这只有在父目录也是一个包的情况下才有效(PVAnalysis 应该包含__init__.py),因为两个点.. 只是意味着上一个目录/模块级。 PVAnalysis 确实包含__init__.py,除非我误解了 【参考方案1】:

为了使包导入在 Python 3 中正常工作,您的工作目录必须是 LabAnalysisModulesPVAnalysis 的父级(或者说该目录必须出现在 sys.path 上,但将其设为工作目录是最简单的方法来做到这一点)。此外,如果您的任何模块是可运行的,则必须使用如下语法调用它们:

python -m 'PVAnalysis.AnalysisWindows.AnalysisWidget'

更多信息请咨询PEP 328。

【讨论】:

通读 PEP 328 我仍然不明白为什么,在 AnalysisWidget.py 中,from ..DataViewer import DataViewer 不起作用。这是在 MainWindow.py 中调用 import AnalysisWindows.AnalysisWidget。在我看来,这与 PEP 中的 from ..moduleA import foo 示例相同 那是因为你跨越了***包的边界。如果要从单独的***包中导入某些内容,则需要使用绝对导入。 对不起,我还是不明白你的意思。我上面介绍的文件/包结构与 PEP 中的文件/包结构有何不同,以至于我所做的事情是无效的(感谢您对此的支持) 哦,我误解了你。如果PVAnalysis 包含在sys.path 中列出的目录之一中,那应该 起作用。由于工作目录始终在该列表中,您只需确保工作目录是PVAnalysis,并且不是 PVAnalysis 本身。跨度> 如果 PVAnalysis 是工作目录?最终,这将是一个应用程序,其中有一个 PVAnalysis.py 文件,用于设置所有内容并将它们放在一起。该文件夹实际上是 PVAnalysis 只是一个容器,让我保持一切井井有条。

以上是关于对如何从模块中的其他目录/父目录导入感到困惑(python 3)的主要内容,如果未能解决你的问题,请参考以下文章

从 Cloud Functions 中的父目录或同级目录导入模块?

Eclipse 对导入感到困惑(“可从多个模块访问”)

父目录中模块的相对导入

如何从 Python 中的子文件夹导入模块或文件?

如何从 aws lambda 中的 git 子模块导入代码?

如何从python中的测试模块导入src