Python:项目、包、模块与库

B站影视 内地电影 2025-10-01 00:26 1

摘要:在 Python 编程中,项目、包、模块与库/分发件是构建与组织代码的基石。理解它们的边界与联系,有助于合理规划目录结构、提升可维护性与复用性。

在 Python 编程中,项目、包、模块与库/分发件是构建与组织代码的基石。理解它们的边界与联系,有助于合理规划目录结构、提升可维护性与复用性。

一、项目

项目(Project)是一个完整的软件工程集合,既包含源代码,也包含构建、测试、文档与配置等配套内容。

1、常见组成

一个或多个包/模块(源码)

构建与依赖:pyproject.toml(或早期的 setup.cfg/setup.py)

环境锁定:requirements.txt(部署环境用)

测试代码:tests/

文档与说明:README.md、LICENSE

版本控制信息:.git/

2、推荐目录结构(src 布局)

my_project/ ← 项目根目录│├── pyproject.toml ← 构建元数据与依赖(推荐)├── requirements.txt ← 部署/环境锁定(可选)├── README.md ← 项目说明├── LICENSE ← 许可证│├── src/ ← 源代码根目录(库项目推荐使用)│ └── my_package/ ← 顶层包(regular 或 namespace)│ ├── __init__.py ← 常规包需要;命名空间包不需要│ ├── module_a.py│ └── module_b.py│└── tests/ ← 测试代码(pytest 等)

提示:

应用型项目可使用平铺布局。

库项目推荐使用 src 布局,以避免“测试能导入,但安装后失败”的问题。

二、包

包(Package)用于分层组织模块,支持点号分隔的层级命名,如:

my_package.subpkg.module_x

1、分类

(1)常规包(regular package)

目录中包含 __init__.py(可为空)。

导入时会创建包对象并执行 __init__.py 中的初始化代码。

可在 __init__.py 中定义 __all__ 来控制 from pkg import * 的导出。

(2)命名空间包(namespace package,Python 3.3+)

目录中不包含 __init__.py。

允许将同名顶层包拆分到多个目录/分发件中,例如多个 wheel 共同提供 my_package 的不同子包。

没有 __init__.py,因此不能在导入时执行初始化逻辑;一些属性如 __file__ 不可用。

导入示例:

# src/my_package/module_a.pydef add(x, y):return x + y# 另一个模块import my_package.module_afrom my_package.module_a import addprint(add(2, 3)) # 输出 5

提示:

对外 API 推荐使用绝对导入。

包内部可用相对导入,如:

from .module_a import add from ..subpkg import util

三、模块

模块(Module)是 Python 程序组织与导入的基本单元,不仅仅是 .py 文件。

1、模块类型

纯 Python 源文件:xxx.py

编译扩展模块:xxx.pyd(Windows)/xxx.so(Linux/macOS)

内建模块:由解释器内置(如 sys)

包的子模块(包目录+子文件)

2、特点

文件名即模块名(不含后缀)

模块提供独立命名空间,便于复用与维护

模块不仅能导入,还能直接运行。

3、模块与脚本

在 Python 中,脚本(script)不是独立概念,而是模块的一种使用方式。

作为模块:通过 import 使用

from my_package import module_amodule_a.some_function

作为脚本:

# 直接运行文件python module_a.py# 或通过 -m 参数运行模块python -m my_package.module_a

惯例写法:

提示:

当文件以脚本运行时,__name__ == "__main__"。

当文件作为模块导入时,__name__ 等于模块名。

四、库 / 分发件

分发件(distribution)指的是面向发布/安装的产物(wheel/sdist)。在日常口语中常被称作 “库”(library),但在严格语境下,库是功能集合,而分发件是发布形态。

1、类型

标准库:随解释器一起发布(如 os、sys、math)。

第三方库:发布在 PyPI 或私有仓库(如 requests、numpy、pandas)。

形态上可以是:

单模块库(一个 .py)

单包库(一个包目录)

多包/多模块的组合

2、分发与安装关键点

(1)分发格式

wheel(.whl):已构建好的二进制/纯 Python 分发件,安装快。

sdist(源分发):源码压缩包,安装时本地构建。

(2)依赖声明

在 pyproject.toml([project] dependencies = [...])中声明运行依赖;

测试/开发依赖可写在工具配置段(如 tool.poetry、tool.uv),或额外维护 requirements-dev.txt。

(3)环境锁定

requirements.txt 更适用于部署环境(可固定版本号),不建议用它作为分发元数据的来源。

3、要点对比

包:导入层面的对象(目录+__init__.py 或命名空间包)。

库/分发件:发布与安装层面的对象(wheel/sdist)。

一个库通常作为分发件发布,内部可能包含一个或多个包/模块。

五、补充说明

1、项目 vs 库

项目面向运行,库面向复用。一个项目也可同时提供命令行入口和 API。

2、包 vs 普通目录

常规包有 __init__.py;命名空间包无 __init__.py;普通目录不可导入。

3、模块 vs 脚本

模块可导入;脚本是运行方式,本质仍是模块。

4、库 vs 框架

框架(如 Django)约束更强,通常控制应用结构;库仅提供功能调用。

5、导入路径

解释器按 sys.path 搜索,安装的包位于 site-packages。

六、命名空间包示例(进阶)

目录 A(分发件 A):

src/└── myns/ ← 无 __init__.py└── alpha/└── a.py

目录 B(分发件 B):

src/└── myns/ ← 无 __init__.py└── beta/└── b.py

安装两者后,导入路径统一聚合为同一个顶层包 myns:

from myns.alpha import afrom myns.beta import b

注意:若放入 __init__.py 就不再是命名空间包,无法跨分发件聚合;并且命名空间包不支持在导入时执行初始化逻辑。

七、实践建议

1、做库

采用 src 布局,pyproject.toml 声明依赖,用 wheel 分发。

2、做应用

可平铺或 src 布局;入口可用 __main__.py 或 console_scripts。

3、包选择

除非需要多仓库聚合,否则使用常规包。

4、导入风格

对外 API 用绝对导入;包内可用相对导入。

5、测试

源码与 tests/ 并列,确保通过“已安装”方式导入。

小结

模块(module):既可导入也可直接执行的代码单元(.py 文件、内建模块、扩展模块等)。

包(package):包含层级命名的模块容器(常规包或命名空间包)。

项目(project):包含代码、配置、测试、文档等内容的完整工程集合。

分发件(distribution):面向发布与安装的产物(wheel/sdist)。日常口语常称“库”,严格来说库是功能集合,而分发件是其发布形态。

“点赞有美意,赞赏是鼓励”

来源:豆豆妈

相关推荐