对如何从模块中的其他目录/父目录导入感到困惑(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 中正常工作,您的工作目录必须是 LabAnalysisModules
和 PVAnalysis
的父级(或者说该目录必须出现在 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 中的父目录或同级目录导入模块?