问题
我的项目有一个目录结构,它遵循 Python 包的标准,因为它是使用这个 cookiecutter 模板创建的: https ://github.com/audreyr/cookiecutter-pypackage#quickstart
目录结构是
project_name
├── project_name
│ ├── __init__.py
│ └── module1.py
└── tests
└── test_module1.py
的第一行代码test_module1.py
是:
from project_name import module1
但我得到一个ModuleNotFoundError: No module named 'project_name'
.
据我了解,这应该可以工作,因为调用的文件夹project_name
是一个包,这是通过__init__.py
文件的存在来确保的。
我一直很难理解像这样的导入是如何工作的。对于我的项目,我总是将我的测试与要测试的模块放在同一个文件夹中。我知道这是不好的做法,但我可以让模块实际导入的唯一方法。
我已经尝试过的
我尝试将包含文件的__init__.py
文件夹重命名为其他名称,然后导入,因为我认为它可能与父文件夹和子文件夹都具有名称有关project_name
。这不起作用,同样的错误。
我还尝试通过在其中创建一个文件将测试文件夹制作成一个包__init.py__
,即使 Cookiecutter 模板没有它。我在很多地方读到不鼓励将测试文件夹打包成一个包,但有些人建议采用这种结构。那也没有用。
我已经彻底搜索了这个看似非常标准的问题的解决方案,一些链接在这里:
- Python,导入模块进行测试
- https://gist.github.com/tasdikrahman/2bdb3fb31136a3768fac
- 从父文件夹导入模块
- https://alex.dzyoba.com/blog/python-import/
- 兄弟包导入
- 使用nose进行测试的Python导入-在当前包之上导入模块的最佳实践是什么
我最后一次尝试是用 Cookiecutter 启动一个项目,所以一切都会从一开始就正确设置。但是,我仍然得到ModuleNotFoundError
.
我不想要的
我不想修改sys.path
似乎暗示的许多答案。对于这样一个常见的问题,必须有一种更清洁的方法。
我究竟做错了什么?
编辑一些额外的信息(见@Nicholas的问题):
的内容__init__.py
是
# -*- coding: utf-8 -*-
"""Top-level package for project_name."""
__author__ = """my_name"""
__email__ = 'my_email'
__version__ = '0.1.0'
这是由 Cookiecutter 模板生成的。
在里面test_module1
,我在发生之前添加了以下内容ModuleNotFoundError
:
import sys
import os
print(sys.path)
print(os.getcwd())
sys.path
打印一个列表,其中第一个元素是tests
目录。
['c:\\Users\\...\\project_name\\tests',
'C:\\Users\\...\\Miniconda3\\python37.zip',
'C:\\Users\\...\\Miniconda3\\DLLs', 'C:\\Users\\...\\Miniconda3\\lib',
'C:\\Users\\...\\Miniconda3',
'C:\\Users\\...\\Miniconda3\\lib\\site- packages',
'C:\\Users\\...\\Miniconda3\\lib\\site-packages\\win32',
'C:\\Users\\...\\Miniconda3\\lib\\site-packages\\win32\\lib',
'C:\\Users\\...\\Miniconda3\\lib\\site-packages\\Pythonwin']
我不知道第一个元素中的小写“c”是否重要。
os.getcwd()
打印根目录'c:\Users\....\project_name'
。还有一个小写的“c”。