强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Python 编程教程 / 11 - 模块与包

第 11 章:模块与包

理解 Python 的模块系统、导入机制和包管理,组织大型项目代码。


11.1 模块基础

11.1.1 什么是模块?

一个 .py 文件就是一个模块。模块可以包含函数、类、变量。

# math_utils.py
"""数学工具模块。"""

PI = 3.14159

def add(a: int, b: int) -> int:
    return a + b

def circle_area(radius: float) -> float:
    return PI * radius ** 2

11.1.2 导入方式

# 导入整个模块
import math_utils
print(math_utils.add(1, 2))

# 导入特定成员
from math_utils import add, PI
print(add(1, 2))

# 别名导入
import math_utils as mu
print(mu.circle_area(5))

# 导入所有(不推荐)
from math_utils import *

11.1.3 模块的 __name__

# math_utils.py
def add(a, b):
    return a + b

if __name__ == "__main__":
    # 只在直接运行时执行
    print(f"2 + 3 = {add(2, 3)}")
$ python math_utils.py   # 输出: 2 + 3 = 5
$ python -c "import math_utils"  # 不输出

11.2 包

11.2.1 包的结构

mypackage/
├── __init__.py        # 包初始化(可以为空)
├── core.py            # 子模块
├── utils.py
└── subpackage/
    ├── __init__.py
    └── helpers.py

11.2.2 __init__.py

# mypackage/__init__.py

# 控制 from mypackage import * 的行为
__all__ = ["core", "utils"]

# 包级别的初始化代码
__version__ = "1.0.0"

# 便捷导入
from .core import important_function
from .utils import helper

11.2.3 使用包

# 方式一:完整路径
from mypackage.core import important_function
from mypackage.subpackage.helpers import helper

# 方式二:通过 __init__.py 暴露的接口
from mypackage import important_function

# 方式三:导入子包
import mypackage.subpackage.helpers

11.3 导入机制

11.3.1 搜索路径

import sys
print(sys.path)
# [
#   '',                      # 当前目录
#   '/usr/lib/python312.zip',
#   '/usr/lib/python3.12',
#   '/usr/lib/python3.12/lib-dynload',
#   '/home/user/.venv/lib/python3.12/site-packages',
# ]
# 动态添加搜索路径
import sys
sys.path.insert(0, "/my/custom/path")
sys.path.append("/another/path")

11.3.2 导入过程

import mymodule

1. 搜索模块(sys.path)
2. 检查 sys.modules 缓存
3. 加载模块代码
4. 执行模块顶层代码
5. 将模块绑定到 sys.modules["mymodule"]
import sys

# 查看已导入的模块
print("json" in sys.modules)  # True(已被标准库预导入)

# 查看模块信息
import json
print(sys.modules["json"])    # <module 'json' from '...'>

11.3.3 相对导入

# mypackage/core.py

# 相对导入(使用 . 或 ..)
from . import utils               # 同包的 utils
from .utils import helper         # 同包的 utils 中的 helper
from .. import other_module       # 上级包的 other_module
from ..subpackage import helpers  # 同级子包

# ⚠️ 相对导入只能在包内部使用,不能在脚本顶层使用

11.3.4 导入的最佳实践

# ✅ 标准库 → 第三方库 → 本地模块(用空行分隔)
import os
import sys
from datetime import datetime

import requests
import numpy as np

from myproject.utils import helper
from myproject.models import User

11.4 高级主题

11.4.1 命名空间包(PEP 420)

# 允许将包分散在多个目录中
# 目录结构 A:
#   mynamespace/package_a/module_a.py
# 目录结构 B:
#   mynamespace/package_b/module_b.py

# 不需要 __init__.py
# 两个目录都加入 sys.path 后,可以同时导入
from mynamespace.package_a import module_a
from mynamespace.package_b import module_b

11.4.2 延迟导入

def process_image(path: str):
    """只在函数调用时才导入(减少启动时间)。"""
    from PIL import Image  # 延迟导入
    img = Image.open(path)
    return img

11.4.3 __all__ 控制导出

# utils.py
__all__ = ["public_function", "PublicClass"]

def public_function():
    pass

def _private_function():
    pass

class PublicClass:
    pass

class _PrivateClass:
    pass
from utils import *  # 只导入 public_function 和 PublicClass

11.4.4 模块级别魔术变量

# mymodule.py
print(__name__)      # "__main__" 或 "mymodule"
print(__file__)      # /path/to/mymodule.py
print(__doc__)       # 模块文档字符串
print(__package__)   # 包名或 None
print(__loader__)    # 模块加载器
print(__spec__)      # 模块规范

11.5 常用标准库模块速查

模块 用途
os 操作系统接口
sys 系统参数和函数
pathlib 面向对象的路径操作
json JSON 编解码
re 正则表达式
datetime 日期和时间
collections 高级容器
itertools 迭代器工具
functools 函数工具
typing 类型注解
logging 日志
unittest 单元测试
argparse 命令行参数
subprocess 子进程管理
threading 线程
multiprocessing 多进程
asyncio 异步 I/O
dataclasses 数据类
abc 抽象基类
contextlib 上下文管理器工具

11.6 注意事项

🔴 注意

  • 循环导入会导致 ImportError,使用延迟导入或重构代码解决
  • from module import * 会污染命名空间,避免使用
  • 相对导入在直接运行脚本时不工作,使用 -m 标志运行
  • 不要在 __init__.py 中放太多逻辑

💡 提示

  • 使用 __all__ 明确导出接口
  • 包内的模块之间使用相对导入
  • 使用 if __name__ == "__main__" 保护脚本入口
  • 大型项目使用 src/ 布局避免导入问题

📌 业务场景

# 项目结构
# myproject/
# ├── __init__.py
# ├── config.py      # 配置
# ├── models/         # 数据模型
# │   ├── __init__.py
# │   ├── user.py
# │   └── order.py
# ├── services/       # 业务逻辑
# │   ├── __init__.py
# │   └── order_service.py
# └── api/            # API 接口
#     ├── __init__.py
#     └── routes.py

# services/order_service.py
from ..models.user import User
from ..models.order import Order
from ..config import settings

class OrderService:
    def create_order(self, user: User, items: list) -> Order:
        ...

11.7 扩展阅读