前言

本文总结了 Python 项目结构的知识,规范项目结构能使得项目开发过程高效流畅,提升代码可读性、团队协作效率,并便于维护、扩展和共享。

参考文章:
各类 Python 项目的项目结构及代码组织最佳实践

前置知识

什么是 Package(包)

包(Package)是一个文件夹,用于存放相关模块、子包、说明文档和配置文件,通常与项目的工程文件夹相对应。包能够将相关模块按功能组织,避免文件混乱。如果你有 STM32 等项目经验,这会更易理解。
ps:
包目录中必须包含 __init__.py 文件,以表明该文件夹是包。若缺少 __init__.py,Python 将无法识别该文件夹为包,导入时会报错。
Package包与 Directories目录的区别:虽然在外观上,Package 和普通目录类似,但包目录中必须包含 __init__.py 文件,而普通目录没有这个要求。包是为了组织 Python 代码模块而存在的,是 Python 中代码管理和复用的方式。

什么是 Module(模块)

模块(Module)是 Python 中的代码文件,一般是 .py 后缀的文件,用于存放可以复用的函数、类或变量等代码。模块使代码更易管理和复用。每个 .py 文件都可以看作是一个独立的模块,可以通过 import 语句在其他代码中使用。

Package 包与 Module 模块的关系
在这里插入图片描述

Package 包可以包含多个 Module 模块。包是模块的集合,它通过将多个相关的模块组合在一起,形成一个结构化的代码体系,从而方便代码的组织、分发和复用。

__init__.py 详解

__init__.py 文件的作用是让 Python 识别某个目录为包,同时可以在其中定义一些包的初始化逻辑,例如导入子模块等。如果 __init__.py 为空,表示这是一个基础的包,包含了默认的模块结构。自 Python 3.3 之后,即使没有 __init__.py,Python 也能识别包,但为了兼容性和代码规范,通常还是建议保留该文件。

Python 的基本项目结构

假设项目名称为 myproject,一个标准的项目结构如下:

myproject/              # 根目录
│  .gitignore      
│  LICENSE           
│  readme.md          
│  requirements.txt     
│  setup.py            
│
├─myproject/            # 包目录 (项目核心模块代码)
│      main.py          # 主函数,程序的入口
│      module1.py       # 模块1代码
│      module2.py       # 模块2代码
│      __init__.py      # 初始化文件
│
└─test/                 # 测试目录
        test_main.py    # 测试 main.py 中的功能

项目根目录说明

  • .gitignore:用于记录不希望提交到版本控制系统(如 Git)的文件,例如虚拟环境、编译生成的文件、日志等。(Git是一个帮助多人协作开发和管理代码的工具,它可以记录每次修改)
  • LICENSE:项目的许可说明文件,定义代码的使用权限。如果是个人或比赛项目,可以省略。
  • readme.md:项目的说明文档,提供项目的基本信息、功能介绍、安装方法、使用说明等。通常是项目的第一份文档,便于其他人快速了解项目。
  • requirements.txt:列出项目所需的第三方依赖库及其版本,便于其他人通过 pip install -r requirements.txt 快速配置项目环境。
  • setup.py:一键配置项目环境的打包配置文件,定义项目的基本信息(如名称、版本、作者、依赖库等),以及指定如何将代码打包成可安装的形式。

对于比赛或小项目,项目结构可以简化,.gitignore、LICENSE、requirements.txt和 setup.py可适当忽略

包目录说明

  • 包目录 (myproject/)
    • main.py:通常是项目的主入口,用于实现项目的逻辑。
    • modulex.py:模块代码,用于实现模块的基本功能
    • __init__.py:初始化操作(如 import)

测试目录说明

  • 测试目录 (test/)
    • test_main.py:测试代码,通常以 test_ 开头,用于对项目中的模块和函数进行单元测试,确保项目的稳定性和正确性。

int main()def main() 的区别

在 C 语言中,int main() 是程序的入口。而在 Python 中,没有固定的入口函数,但通常 main.py 被作为程序的入口文件。在 PyCharm 中,新建工程时默认会创建一个 main.py 文件(PyCharm的期望入口),你可以在其中 import 其他模块并调用它们的功能。
此外,也可以在 main.py 中 def 一个 main() 函数,并通过以下方式确保该函数只有在直接运行时才会执行:

if __name__ == "__main__":
    main()

这种写法确保了当 Python 文件被直接执行时调用 main(),但如果文件作为模块导入时,主函数不会自动执行。

举例:基于 KNN 的 OpenCV 数字识别的项目结构

knn_digit_recognition/
├── data/                             # 数据集目录
│   ├── train_images/                 # 训练集图片
│   ├── train_labels.csv              # 训练标签(如 CSV 文件,存储图片与标签的对应关系)
│   ├── test_images/                  # 测试集图片
│   └── test_labels.csv               # 测试标签
│
├── src/                              # 源代码目录(包目录)
│   ├── __init__.py                   # 标识 src 为包,初始化代码
│   ├── preprocess.py                 # 图像预处理代码(灰度、阈值、缩放等)
│   ├── knn_model.py                  # KNN 模型代码,包括训练和预测
│   ├── utils.py                      # 辅助函数(如数据加载、文件管理等)
│   └── main.py                       # 主程序,项目入口
│
├── tests/                            # 测试代码
│   ├── test_preprocess.py            # 测试预处理模块
│   ├── test_knn_model.py             # 测试 KNN 模型
│   └── test_main.py                  # 测试主程序流程
│
├── .gitignore                        # Git 忽略文件
├── requirements.txt                  # 项目依赖项
├── README.md                         # 项目说明文档
└── setup.py                          # 安装和配置脚本
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐