【Python】基础语法入门(二十二)——模块与包:组织你的代码,打造可复用的 Python 项目
2026/5/11 4:23:43 网站建设 项目流程


📦说明:当你的代码从几十行增长到几百、几千行,良好的组织结构就变得至关重要。本篇深入讲解 Python 的模块(Module)与包(Package)系统,教你如何将代码拆分为逻辑清晰、易于维护、可复用的单元,并掌握import的各种用法与最佳实践。

你将学会:

  • 模块 vs 包的区别
  • 如何创建和导入自定义模块
  • __init__.py的作用与演进
  • 绝对导入 vs 相对导入
  • 避免循环导入的技巧
  • 发布自己的包(简要介绍)

1. 为什么需要模块化?

❌ 单文件项目的痛点

my_app.py (2000 行) ├── 数据库操作 ├── 用户认证 ├── 文件处理 ├── Web 路由 └── 工具函数
  • 难以阅读和维护
  • 无法复用部分功能
  • 团队协作冲突多

✅ 模块化的优势

my_app/ ├── main.py ├── auth/ ← 用户认证模块 │ ├── __init__.py │ └── login.py ├── db/ ← 数据库模块 │ ├── __init__.py │ └── models.py └── utils/ ← 工具函数 ├── __init__.py └── helpers.py
  • 高内聚:相关功能放在一起
  • 低耦合:模块间依赖清晰
  • 可复用utils可被其他项目使用
  • 易测试:可单独测试每个模块

2. 模块(Module)基础

什么是模块?

  • 任何.py文件都是一个模块
  • 模块名 = 文件名(不含.py

示例:创建工具模块

# utils/math_tools.pydefadd(a,b):returna+b PI=3.14159

导入方式

# 方式1:完整导入importutils.math_toolsprint(utils.math_tools.add(2,3))# 方式2:重命名(推荐长模块名时使用)importutils.math_toolsasmtprint(mt.PI)# 方式3:导入特定成员fromutils.math_toolsimportadd,PIprint(add(1,2))# 方式4:导入所有(不推荐!污染命名空间)fromutils.math_toolsimport*

⚠️避免import *

  • 不清楚导入了什么
  • 可能覆盖同名变量
  • 破坏代码可读性

3. 包(Package):模块的容器

包的定义

  • 包含__init__.py的目录(Python 3.3+ 可省略,但建议保留)
  • 可嵌套(子包)

创建包结构

mypackage/ ├── __init__.py ← 标记为包(可为空) ├── core.py └── utils/ ├── __init__.py └── string_ops.py

__init__.py的作用

  1. 标记目录为包(必需,除非使用 PEP 420 命名空间包)
  2. 控制导入行为(如暴露哪些接口)
  3. 执行包初始化代码
示例:简化导入
# mypackage/__init__.pyfrom.coreimportmain_functionfrom.utils.string_opsimportclean_text# 外部只需:frommypackageimportmain_function,clean_text

💡现代建议:即使为空,也保留__init__.py以明确意图。


4. 导入机制详解

4.1 绝对导入(Absolute Import)

项目根目录或 sys.path开始导入。

# 项目根目录下执行frommypackage.coreimportmain_functionfrommypackage.utils.string_opsimportclean_text

优点:路径清晰,不易出错
推荐用于:所有新项目


4.2 相对导入(Relative Import)

当前模块位置相对导入(仅限包内使用)。

# 在 mypackage/utils/string_ops.py 中from..coreimporthelper_func# 上一级from.formattingimportformat_str# 同级

🔑 规则:

  • .= 当前包
  • ..= 上一级包
  • ...= 上两级

⚠️限制

  • 不能在主脚本(__main__)中使用
  • 必须通过-m运行包(见下文)

5. 正确运行包内的脚本

❌ 错误方式(导致相对导入失败)

# 在 mypackage/ 目录下python core.py# 报错:Attempted relative import in non-package

✅ 正确方式1:从项目根目录运行

# 项目根目录python -m mypackage.core

✅ 正确方式2:在主脚本中使用绝对导入

# main.py (项目根目录)frommypackage.coreimportmain_functionif__name__=="__main__":main_function()

然后运行:

python main.py

📌黄金法则
“永远不要直接运行包内部的 .py 文件!”


6.sys.path与模块搜索路径

Python 按顺序在以下位置查找模块:

  1. 当前脚本目录
  2. PYTHONPATH环境变量
  3. 标准库目录
  4. 第三方包安装目录(site-packages

查看搜索路径

importsysprint(sys.path)

临时添加路径(不推荐长期使用)

importsys sys.path.append("/path/to/your/module")importyour_module

正确做法:通过虚拟环境 + 安装包管理路径


7. 避免循环导入(Circular Import)

问题场景

# file_a.pyfromfile_bimportfunc_bdeffunc_a():returnfunc_b()# file_b.pyfromfile_aimportfunc_a# ← 循环!deffunc_b():return"Hello"

运行file_a.pyImportError

解决方案

方案1:延迟导入(推荐)
# file_b.pydeffunc_b():fromfile_aimportfunc_a# 只在需要时导入returnfunc_a()+" from B"
方案2:重构代码
  • 将共享功能提取到第三个模块
  • 减少模块间直接依赖
方案3:导入移到函数内部
defsome_function():importproblematic_module...

8. 发布你的包(简要流程)

当你想分享代码给他人:

步骤1:创建标准结构

mypackage/ ├── setup.py ← 元数据 ├── README.md ├── mypackage/ │ ├── __init__.py │ └── core.py └── tests/

步骤2:编写setup.py

fromsetuptoolsimportsetup,find_packages setup(name="mypackage",version="0.1.0",packages=find_packages(),install_requires=[],)

步骤3:本地安装(开发模式)

pipinstall-e.# -e 表示可编辑模式

📦 安装后,任何地方都可import mypackage


9. 最佳实践总结

场景推荐做法
导入方式优先绝对导入,包内用相对导入
__init__.py保留(即使为空),用于控制 API
模块命名小写 + 下划线(data_utils.py
避免import *、循环导入、直接运行包内脚本
组织原则按功能划分,而非按类型(如不要建classes/,functions/

🐍Python 之禅
“Flat is better than nested.”(扁平优于嵌套)
—— 但合理分层更重要!


10. 实战:重构 To-Do List 项目

回顾第(二十)篇的项目结构:

todo-cli/ ├── todo.py └── todolib/ ├── __init__.py ├── task.py ├── storage.py └── manager.py

改进建议:

  1. todolib/__init__.py中暴露核心接口
    from.managerimportTaskManagerfrom.taskimportTask __all__=["TaskManager","Task"]
  2. 主程序简化导入
    fromtodolibimportTaskManager# 而非 from todolib.manager import...

下一步行动

  1. 将你的工具函数拆分为独立模块
  2. 尝试创建一个包含多个子包的小型项目
  3. 阅读知名开源项目(如 requests)的包结构

🧱模块化是软件工程的基石。
从今天起,像建筑师一样设计你的代码结构!

继续构建清晰、可维护、可扩展的 Python 项目!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询