网易首页 > 网易号 > 正文 申请入驻

Python:项目、包、模块与库

0
分享至

在 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.py
def add(x, y):
    return x + y

# 另一个模块
import my_package.module_a
from my_package.module_a import add
print(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_a
module_a.some_function()

作为脚本:

# 直接运行文件
python module_a.py

# 或通过 -m 参数运行模块
python -m my_package.module_a

惯例写法:

# foo.py
def main():
    print("Hello")

if __name__ == "__main__":
    main()

提示:

当文件以脚本运行时,__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 a
from 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)。日常口语常称“”,严格来说是功能集合,而分发件是其发布形态。

点赞有美意,赞赏是鼓励

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
访华结束,最后关头中方没有松口,李在明登机回国,留下唯一遗憾

访华结束,最后关头中方没有松口,李在明登机回国,留下唯一遗憾

南宫一二
2026-01-08 16:18:31
CES 2026,中国车来定义“AI+出行”丨品牌新事

CES 2026,中国车来定义“AI+出行”丨品牌新事

吴晓波频道
2026-01-09 08:33:40
刚说川普可能护送巴列维进入,就传伊朗断网和川普可能再次打击

刚说川普可能护送巴列维进入,就传伊朗断网和川普可能再次打击

邵旭峰域
2026-01-09 12:56:47
朴槿惠出狱生活:住别墅,与小10岁律师为伴,如今生活安逸

朴槿惠出狱生活:住别墅,与小10岁律师为伴,如今生活安逸

策略述
2026-01-09 13:02:41
已确认,是75岁的王石!

已确认,是75岁的王石!

财经要参
2026-01-08 21:33:30
2299元波司登商务羽绒服充绒量仅86克,网友质疑品牌溢价过高,客服回应

2299元波司登商务羽绒服充绒量仅86克,网友质疑品牌溢价过高,客服回应

极目新闻
2026-01-08 22:29:38
突发!Manus交易大概率要黄了!

突发!Manus交易大概率要黄了!

达文西看世界
2026-01-09 12:55:01
“一家三口被撞亡案”被告廖某宇被判死缓,被害人母亲:他面无表情,其父全程戴口罩;被害人律师:将会申请抗诉

“一家三口被撞亡案”被告廖某宇被判死缓,被害人母亲:他面无表情,其父全程戴口罩;被害人律师:将会申请抗诉

极目新闻
2026-01-09 11:19:24
雷军再回应"1300公里只充一次电" 水军想给我贴"虚假营销"的标签

雷军再回应"1300公里只充一次电" 水军想给我贴"虚假营销"的标签

每日经济新闻
2026-01-09 10:29:49
特朗普接受专访:“我不需要国际法”

特朗普接受专访:“我不需要国际法”

澎湃新闻
2026-01-09 13:57:08
特朗普称取消对委内瑞拉第二波打击

特朗普称取消对委内瑞拉第二波打击

界面新闻
2026-01-09 17:28:08
明朝的强弩不过能射50步远,为什么战国时期的强弩却能射600步?

明朝的强弩不过能射50步远,为什么战国时期的强弩却能射600步?

铭记历史呀
2026-01-09 06:15:36
三星展示近乎无折痕OLED面板,或为苹果iPhone Fold准备

三星展示近乎无折痕OLED面板,或为苹果iPhone Fold准备

科技兽
2026-01-06 21:57:25
队记:这是杨瀚森本赛季打得最好的一场 真正做到了能被教练用上

队记:这是杨瀚森本赛季打得最好的一场 真正做到了能被教练用上

罗说NBA
2026-01-09 07:36:38
回顾许家印被抓捕现场,奋力反抗,怒吼不已,被抓捕人员抬出去

回顾许家印被抓捕现场,奋力反抗,怒吼不已,被抓捕人员抬出去

干史人
2026-01-08 22:47:00
森林狼超湖人升西部第四!爱德华兹突破1万分 比肩科比詹姆斯

森林狼超湖人升西部第四!爱德华兹突破1万分 比肩科比詹姆斯

Emily说个球
2026-01-09 12:40:30
山姆499元羽绒服充绒400克卖爆,多个门店已断货,二手平台有人加价数十元出售,客服:补货时间未知

山姆499元羽绒服充绒400克卖爆,多个门店已断货,二手平台有人加价数十元出售,客服:补货时间未知

极目新闻
2026-01-09 12:45:05
中央决定,赵建军履新

中央决定,赵建军履新

上观新闻
2026-01-09 15:41:06
广东省珠海市委常委、统战部部长郭才武接受审查调查

广东省珠海市委常委、统战部部长郭才武接受审查调查

界面新闻
2026-01-09 17:03:02
让白宫心惊肉跳!中方推出星链终端干扰设备,而且大大方方展出!

让白宫心惊肉跳!中方推出星链终端干扰设备,而且大大方方展出!

我心纵横天地间
2026-01-08 22:42:39
2026-01-09 17:55:00
MediaTea
MediaTea
专业的数字媒体、新媒体技术
1695文章数 72关注度
往期回顾 全部

科技要闻

市场偏爱MiniMax:开盘涨42%,市值超700亿

头条要闻

10岁抗癌"小王子"病情加重:用药都已无效 不能吃饭

头条要闻

10岁抗癌"小王子"病情加重:用药都已无效 不能吃饭

体育要闻

金元时代最后的外援,来中国8年了

娱乐要闻

檀健次恋爱风波越演越烈 上学经历被扒

财经要闻

投资必看!瑞银李萌给出3大核心配置建议

汽车要闻

英伟达的野心:做一套自动驾驶的“安卓系统”

态度原创

房产
本地
旅游
时尚
公开课

房产要闻

66万方!4755套!三亚巨量房源正疯狂砸出!

本地新闻

云游内蒙|“包”你再来?一座在硬核里酿出诗意的城

旅游要闻

冬日入川,踏雪寻暖,赴一场冰与火的诗意邀约|长图

60+女性穿搭“高级感”秘诀:4个日常技巧,轻松美出优雅气质

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版