摘要
我具有以下目录结构。我的目标是使module1可导入(在本例中为test_module1.py),当我在module1目录中时,也可以直接调用module1.py。我觉得这是一个很好的解决方案,或者我构建应用程序的方式出了问题,因此欢迎您提出建议的解决方案或对应用程序结构进行更改
详细信息
目录结构
.
├── module1
│ ├── __init__.py
│ ├── module1.py
│ ├── module2
│ │ ├── __init__.py
│ │ └── module2.py
└── tests
└── test_module1.py
我的文件填充如下
test_module1.py
from module1.module1 import Module1
def test_fake():
pass
module1.py
from module2.module2 import Module2
class Module1:
pass #or regular __init__, etc
module2.py
class Module2:
pass #or regular __init__, etc
所以我希望能够
1)从module1目录中运行module1
cd module1
python module1.py
2)使用
从主目录运行测试pytest
在上述情况下,#1有效,但#2失败
from module1.module1 import Module1
E ModuleNotFoundError: No module named 'module1'
这是由于pytest仅在模块的测试目录中进行检查。通过运行python -m pytest
可以解决该问题,它可以查看.
目录
但是,仍然存在错误,这是我无法弄清的。
Traceback:
tests/test_module1.py:1: in <module>
from module1.module1 import Module1
module1/module1.py:1: in <module>
from module2.module2 import Module2
E ModuleNotFoundError: No module named 'module2.Module2'
经过测试的解决方案
该测试找到module1,但是在导入module1时,它需要找到module2。它在.
目录中查找,但不在./module1
目录中查找。可以通过将module1.py中的导入从from module2.module2 import Module2
更改为from .module2.module2 import Module2
来解决(请注意在开头添加了.
)。这是相对导入,绝对导入也可以解决此问题。两种解决方案都使python -m pytest
通过,因此#2可以工作。但是,两者都破坏了功能#1,在这里我希望能够直接从模块内部运行module1。再往前走,我尝试从.
运行module1.py,这给出了错误:No module named '__main__.module2'; '__main__' is not a package
。我终于可以使用python -m module1.module1
使其正常工作,但这似乎是超级环形交叉路口。下面是这些解决方案的更多信息
ModuleNotFoundError: What does it mean __main__ is not a package?
How to do relative imports in Python?
基本上,我发现绝对导入和相对导入现在强制必须使用-m从根目录中调用module1。这似乎向我表明了一个更大的问题,即在python中使用嵌套模块时,较低级别的模块将永远无法单独使用。假设module2包含两个文件,一个需要导入另一个。还将不得不使用相对或绝对导入,现在需要使用-m从module1运行module2,这使得构建这些脚本之一很麻烦。
我觉得我也可能会在__init__.py
文件中做些事情,并在python文档https://docs.python.org/3/reference/import.html#submodules中发现了在__init__.py
中进行相对导入的建议,但这并没有为我工作。
某些背景(可选阅读):我想要这个的原因是
1)我以崇高的文字进行开发,因此我可以在编写代码时直接直接构建文件
2)我花了大量时间研究根据模块和测试构建python应用程序的好方法,这就是我想出的。如果我做错了事,请告诉我,但是如果这是一个很好的结构,那么能够直接在模块中运行代码并能够(从测试脚本或其他地方)导入模块似乎是相当基本的功能,应该是可以实现的。