基于Bing Chat的GPT API封装:低成本AI应用开发实战指南
2026/5/11 4:20:34
📦说明:当你的代码从几十行增长到几百、几千行,良好的组织结构就变得至关重要。本篇深入讲解 Python 的模块(Module)与包(Package)系统,教你如何将代码拆分为逻辑清晰、易于维护、可复用的单元,并掌握
import的各种用法与最佳实践。
你将学会:
__init__.py的作用与演进my_app.py (2000 行) ├── 数据库操作 ├── 用户认证 ├── 文件处理 ├── Web 路由 └── 工具函数my_app/ ├── main.py ├── auth/ ← 用户认证模块 │ ├── __init__.py │ └── login.py ├── db/ ← 数据库模块 │ ├── __init__.py │ └── models.py └── utils/ ← 工具函数 ├── __init__.py └── helpers.pyutils可被其他项目使用.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 *:
- 不清楚导入了什么
- 可能覆盖同名变量
- 破坏代码可读性
__init__.py的目录(Python 3.3+ 可省略,但建议保留)mypackage/ ├── __init__.py ← 标记为包(可为空) ├── core.py └── utils/ ├── __init__.py └── string_ops.py__init__.py的作用# mypackage/__init__.pyfrom.coreimportmain_functionfrom.utils.string_opsimportclean_text# 外部只需:frommypackageimportmain_function,clean_text💡现代建议:即使为空,也保留
__init__.py以明确意图。
从项目根目录或 sys.path开始导入。
# 项目根目录下执行frommypackage.coreimportmain_functionfrommypackage.utils.string_opsimportclean_text✅优点:路径清晰,不易出错
✅推荐用于:所有新项目
从当前模块位置相对导入(仅限包内使用)。
# 在 mypackage/utils/string_ops.py 中from..coreimporthelper_func# 上一级from.formattingimportformat_str# 同级🔑 规则:
.= 当前包..= 上一级包...= 上两级
⚠️限制:
__main__)中使用-m运行包(见下文)# 在 mypackage/ 目录下python core.py# 报错:Attempted relative import in non-package# 项目根目录python -m mypackage.core# main.py (项目根目录)frommypackage.coreimportmain_functionif__name__=="__main__":main_function()然后运行:
python main.py📌黄金法则:
“永远不要直接运行包内部的 .py 文件!”
sys.path与模块搜索路径Python 按顺序在以下位置查找模块:
PYTHONPATH环境变量site-packages)importsysprint(sys.path)importsys sys.path.append("/path/to/your/module")importyour_module✅正确做法:通过虚拟环境 + 安装包管理路径
# file_a.pyfromfile_bimportfunc_bdeffunc_a():returnfunc_b()# file_b.pyfromfile_aimportfunc_a# ← 循环!deffunc_b():return"Hello"运行file_a.py→ImportError
# file_b.pydeffunc_b():fromfile_aimportfunc_a# 只在需要时导入returnfunc_a()+" from B"defsome_function():importproblematic_module...当你想分享代码给他人:
mypackage/ ├── setup.py ← 元数据 ├── README.md ├── mypackage/ │ ├── __init__.py │ └── core.py └── tests/setup.pyfromsetuptoolsimportsetup,find_packages setup(name="mypackage",version="0.1.0",packages=find_packages(),install_requires=[],)pipinstall-e.# -e 表示可编辑模式📦 安装后,任何地方都可
import mypackage
| 场景 | 推荐做法 |
|---|---|
| 导入方式 | 优先绝对导入,包内用相对导入 |
__init__.py | 保留(即使为空),用于控制 API |
| 模块命名 | 小写 + 下划线(data_utils.py) |
| 避免 | import *、循环导入、直接运行包内脚本 |
| 组织原则 | 按功能划分,而非按类型(如不要建classes/,functions/) |
🐍Python 之禅:
“Flat is better than nested.”(扁平优于嵌套)
—— 但合理分层更重要!
回顾第(二十)篇的项目结构:
todo-cli/ ├── todo.py └── todolib/ ├── __init__.py ├── task.py ├── storage.py └── manager.pytodolib/__init__.py中暴露核心接口:from.managerimportTaskManagerfrom.taskimportTask __all__=["TaskManager","Task"]fromtodolibimportTaskManager# 而非 from todolib.manager import...🧱模块化是软件工程的基石。
从今天起,像建筑师一样设计你的代码结构!
继续构建清晰、可维护、可扩展的 Python 项目!