news 2026/4/18 11:04:04

【Python】基础语法入门(二十二)——模块与包:组织你的代码,打造可复用的 Python 项目

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Python】基础语法入门(二十二)——模块与包:组织你的代码,打造可复用的 Python 项目


📦说明:当你的代码从几十行增长到几百、几千行,良好的组织结构就变得至关重要。本篇深入讲解 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 项目!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/11 16:28:45

【原创实践】使用 shell 脚本批量创建 Linux 用户并生成随机密码

在日常 Linux 运维或测试环境中,经常会遇到需要批量创建用户并设置密码的场景,比如: 测试多用户登录教学或实验环境初始化内部系统批量账号准备 手动逐个创建不仅效率低,而且容易出错。本文介绍一种 使用 Bash 脚本 Linux 命令…

作者头像 李华
网站建设 2026/4/18 7:56:25

27、《.NET与Windows Azure的SOA安全解析》

《.NET与Windows Azure的SOA安全解析》 在当今数字化的时代,服务导向架构(SOA)已经成为企业构建应用程序的主流方式。然而,随着SOA的广泛应用,安全问题也日益凸显。本文将深入探讨如何在.NET和Windows Azure平台上实现SOA的安全架构。 订单服务的安全架构设计案例 以St…

作者头像 李华
网站建设 2026/4/17 20:43:53

40、面向服务计算资源与WCF服务消费资源清理指南

面向服务计算资源与WCF服务消费资源清理指南 在面向服务的计算领域,有许多有价值的资源网站能为我们提供丰富的补充内容。同时,在使用Microsoft的Windows Communication Foundation(WCF)来实现服务和服务消费者时,资源的清理是一个关键问题。下面将为大家详细介绍相关的资…

作者头像 李华
网站建设 2026/4/9 17:25:26

机器学习003:无监督学习(概论)--机器如何学会“自己整理房间”

想象一下,你面对一个从未整理过的、堆满各种物品的房间。没有人告诉你“书应该放书架”“衣服该进衣柜”,但你能自然而然地根据物品的形状、颜色、材质,把相似的东西归在一起。这种不依赖明确指令,仅凭观察事物本身来发现规律的能…

作者头像 李华
网站建设 2026/4/17 10:45:12

智能对话界面构建终极指南:快速上手MateChat的完整教程

智能对话界面构建终极指南:快速上手MateChat的完整教程 【免费下载链接】MateChat 前端智能化场景解决方案UI库,轻松构建你的AI应用,我们将持续完善更新,欢迎你的使用与建议。 官网地址:https://matechat.gitcode.com …

作者头像 李华
网站建设 2026/4/18 10:49:26

xUtils3终极指南:快速掌握Android四大核心开发利器

xUtils3终极指南:快速掌握Android四大核心开发利器 【免费下载链接】xUtils3 Android orm, bitmap, http, view inject... 项目地址: https://gitcode.com/gh_mirrors/xu/xUtils3 xUtils3是一款轻量级且功能强大的Android开发工具库,它将复杂的开…

作者头像 李华