【发布时间】:2015-08-04 12:47:34
【问题描述】:
无论我如何在代码文件和__init__.py 文件中构建导入,我似乎都无法正确执行程序和使用pytest 运行测试.当我的项目结构如下时,我需要如何编写导入:
src/
__init__.py
VocableFileWriter.py
WordListHelper.py
WordListReader.py
XLDAttributeValueAdder.py
exceptions/
__init__.py
XMLInvalidException.py
XMLParseException.py
gui/
__init__.py
GTKSignal.py
XLDAttributeValueAdderWindow.py
test/
__init__.py
test_XLDAttributeValueAdder.py
xmlparser/
__init__.py
XMLParser.py
目前我有这样的:
在 __init__.py 文件中,我有这样的导入 (src/__init__.py):
from src import *
from src.exceptions import *
from src.xmlparser import *
在一个子包中 (src/xmlparser/__init__.py):
from src.xmlparser import *
所以我猜这些是模块的绝对项目路径。 在代码文件本身中,我像这样导入:
import os
import sys
from VocableFileWriter import VocableFileWriter
from XLDAttributeValueAdder import XLDAttributeValueAdder
但是,当我从src 上面的目录中执行代码时,使用:
./src/main.py
它告诉我:
Traceback (most recent call last):
File "./src/main.py", line 6, in <module>
from VocableFileWriter import VocableFileWriter
File "/home/xiaolong/Development/PycharmProjects/xld-attribute-value-adder/src/VocableFileWriter.py", line 2, in <module>
from XMLInvalidException import XMLInvalidException
ImportError: No module named 'XMLInvalidException'
它曾经是一个 PyCharm 项目,但是当我不使用 PyCharm 而是从终端运行它时,我无法使用导入结构 PyCharm 来运行它,所以我决定将整个导入内容放入我的自己的手。所以不要因为它位于 PyCharm 目录中而感到困惑。
我还希望能够使用以下示例执行测试:
py.test src/test/test_XLDAttributeValueAdder.py
我该如何解决这个烂摊子?
编辑#1: 我让程序运行了一次,但随后测试抱怨缺少模块,可能是因为它在另一个子目录中并且我尝试了很多配置,以至于我不知道我是如何让程序运行的。如果可能的话,请添加一些解释为什么某个结构是正确的并且对测试和程序本身都有效。
编辑#2:
我现在已经设法让测试运行,但现在程序不再运行了。
我清空了所有 __init__.py 文件,并在代码文件中只使用了项目绝对路径,如下所示 (src/test/test_XLDAttributeValueAdder.py):
from src.VocableFileWriter import VocableFileWriter
from src.WordListHelper import WordListHelper
from src.WordListReader import WordListReader
from src.XLDAttributeValueAdder import XLDAttributeValueAdder
from src.exceptions.XMLInvalidException import XMLInvalidException
from src.exceptions.XMLParseException import XMLParserException
from src.xmlparser.XMLParser import XMLParser
from src.test.path_helper import go_up
from src.test.path_helper import go_in
在main.py:
from src.VocableFileWriter import VocableFileWriter
from src.XLDAttributeValueAdder import XLDAttributeValueAdder
./src/main.py的输出:
./src/main.py
Traceback (most recent call last):
File "./src/main.py", line 6, in <module>
from src.VocableFileWriter import VocableFileWriter
ImportError: No module named 'src'
编辑#3: 我试过这样的相对导入方式:
-
main.py上移了一个目录
结构现在看起来像这样:
main.py
src/
__init__.py
VocableFileWriter.py
WordListHelper.py
WordListReader.py
XLDAttributeValueAdder.py
exceptions/
__init__.py
XMLInvalidException.py
XMLParseException.py
gui/
__init__.py
GTKSignal.py
XLDAttributeValueAdderWindow.py
test/
__init__.py
test_XLDAttributeValueAdder.py
xmlparser/
__init__.py
XMLParser.py
-
__init__.py文件为空 -
main.py文件变得相对
导入看起来像这样:
import os
import sys
from .src.VocableFileWriter import VocableFileWriter
from .src.XLDAttributeValueAdder import XLDAttributeValueAdder
当我尝试运行main.py 文件时:
Traceback (most recent call last):
File "main.py", line 6, in <module>
from .src.VocableFileWriter import VocableFileWriter
SystemError: Parent module '' not loaded, cannot perform relative import
但是,与main.py 文件在同一目录中有一个__init__.py 文件,也是空的。
【问题讨论】:
-
main.py 文件不应使用相对导入,当您打算直接调用它时。您将它移到包结构之外,因此它是一个独立的模块,适合对包使用绝对导入。我会澄清我的答案。
标签: python terminal python-import directory-structure pytest