Python导入与

2024-06-28 15:28:30 发布

您现在位置:Python中文网/ 问答频道 /正文

无论我如何在代码文件和__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):

^{pr2}$

在子包(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时使用的imports结构来运行它,而是从终端运行它,所以我决定将整个进口产品交给我自己处理。所以不要因为它在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文件,也是空的。在


Tags: 文件代码infrompytestimportsrc
1条回答
网友
1楼 · 发布于 2024-06-28 15:28:30

你最好用相对进口的。在

当你在import之前定义了import。很可能没什么。如果您已经定义了__all__变量,您将从中获得子模块,但如果变量尚未定义,则可能还会得到一个AttributeError。在

因此,相反,在需要的地方显式地导入所需的模块

from .VocableFileWriter import VocableFileWriter
from .exceptions.XMLInvalidException import XMLInvalidException

或者说在src/gui中/GTKSignal.py

^{pr2}$

也可以使用项目绝对路径,如编辑2中所述。在


此外,在调用./src/main.py时,您的路径有问题。在本例中,包含src的目录不在路径中。{cd6>中的路径是^。因此python不再将其视为一个包,而且由于没有其他具有该名称的包,因此导入失败。在

相反,将您的main.py模块放在与src包相同的目录中,或者将其作为带有python -m src.main的模块调用。你也可以用main调用main。在


当使用第一种方法时,main应该使用绝对导入结构。只需将它看作是您放在计算机上任何地方的模块,而您的src包在其他地方,在那里它可以被Python找到,就像系统安装的任何其他模块或包一样。当它位于包本身之外时,也没有什么不同,因为当前目录在sys.path中。在

主.py

^{3}$

相关问题 更多 >