如何从当前文件夹旁边的文件夹导入一个模块?

22
我已经查阅了尽可能多的SO页面,并尝试了找到的所有方法,但都没有成功。我还查看了有关导入的PEP页面,并尝试了每个示例,但都没有成功。
我有一个测试文件夹,其中包含单元测试,并且我需要导入要测试的模块。这些模块在名为“src”的文件夹中,该文件夹位于src文件夹旁边。
文件夹/文件大致如下所示:
Project / 
        src /
            stringbuilder.py
            __init__.py
        tests / 
            stringbuilder_test.py
            __init__.py
        main.py
        __init__.py
我尝试了所有的方法:将 __init__.py 添加到每个文件夹中并将其变为模块,包括项目的主文件夹。
import src.module_to_test 
from ..src.module_to_test import function_to_test
from ..src import module_to_test

我已经尝试了所有其他的组合,但都失败了。我开始觉得我的设置或理解肯定出了问题——我原以为这很简单。

如果我犯了任何明显的错误,请告诉我。

from tests import stringbuilder

错误信息:

$ ./stringbuilder_test.py
Traceback (most recent call last):
  File "./stringbuilder_test.py", line 14, in <module>
    from tests import stringbuilder
ImportError: No module named tests

对于 (但 tests = src),同样会出现相同的错误:

from src import stringbuilder

你在那个文件夹里有一个 __init__.py 文件吗? - piggy_Yu
是的,在项目文件夹、src文件夹和tests文件夹中都有一个。 - anon
在帖子中添加了一点内容,试图展示层次结构。 - anon
哎呀,它和源代码一起失败了,还有许多其他的尝试。 - anon
“from ..src import stringbuilder” 的确切错误是什么? - John Y
显示剩余8条评论
3个回答

13

如果脚本是从包内执行的,则需要采用各种技巧来使导入工作正常。其中最常见的是操纵 sys.path

import sys, os

sys.path.insert(0,
    os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from src import stringbuilder

del sys.path[0]

使用普通的导入语句无法实现这一点。

一般而言,更好的解决方案是完全避免在包内运行脚本。相反,将所有脚本放在一个包含目录之外。考虑到当前正在运行的脚本所在的目录会自动添加到 sys.path的开头,这将确保可以直接导入包,无论从哪里执行脚本。

因此,目录结构可能如下所示:

project /
    package /
        __init__.py
        src /
            __init__.py
            stringbuilder.py
        tests / 
            __init__.py
            stringbuilder_test.py
    main.py
    test.py

test.py脚本可以像这样导入其测试:

from package.tests import stringbuilder_test

而且stringbuilder_test.py可以像这样导入src模块:

from package.src import stringbuilder

1
from folder import my_module

如果在文件夹中有一个名为__init__.py的文件。

这个失败了,它说没有名为“folder”的模块。 - user427390
嗯,我想你应该用你的文件夹名称替换folder - David Heffernan

-9
将该文件夹添加到您的PATH中。

将其添加到PYTHONPATH略为不堪,但却错过了问题的要点。将其添加到PATH中毫无帮助。 - Wooble

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接