2

问题

我的项目有一个目录结构,它遵循 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 模板没有它。我在很多地方读到不鼓励将测试文件夹打包成一个包,但有些人建议采用这种结构。那也没有用。

我已经彻底搜索了这个看似非常标准的问题的解决方案,一些链接在这里:

我最后一次尝试是用 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”。

4

1 回答 1

1

您应该创建一个虚拟环境并安装项目,以便测试模块正确解析导入语句。

在项目根目录,即project_name包含一个子目录project_name和一个子目录的目录中,为包元数据tests创建一个setup.py(或)文件。pyproject.toml有关该部分的详细信息,请参见此处

从现在包含安装程序 ( setup.py) 的同一个项目根目录中,创建并激活一个 venv 并安装您的项目:

python3 -m venv .venv
source .venv/bin/activatate  # linux/macOS
# .\Scripts\activate.bat  # windows
pip install --editable .
pip install pytest
pytest

如果由于某种原因您不想为您的项目创建安装程序,您可以像这样从项目目录运行 pytest:

python3 -m pytest

与裸pytest命令不同,这会将当前工作目录添加到sys.path允许在测试中解析导入语句。

于 2019-04-27T17:20:23.327 回答