第 7 章 模块、包与导入系统

7.1 模块:一个 .py 文件

任何 .py 文件都是一个模块。把代码按功能拆成模块,是组织代码的第一步。

创建 mymath.py:

PI = 3.14159

def circle_area(r):
    return PI * r ** 2

print("mymath 模块被加载了")     # 演示用,见 7.3

在其他文件中导入:

import mymath                    # 导入整个模块
mymath.circle_area(2)            # 使用:模块名.成员

import mymath as mm              # 别名
mm.PI

from mymath import circle_area, PI   # 导入指定成员
circle_area(2)                   # 直接使用,无需前缀

from mymath import *             # 导入全部(不推荐:命名空间被污染)

7.2 包:带 __init__.py 的目录

包(package)是模块的目录,用于分层组织:

myproject/
└── utils/
    ├── __init__.py          # 标记这是一个包(可为空)
    ├── text.py              # utils.text 模块
    └── net/
        ├── __init__.py
        └── http.py          # utils.net.http 模块
from utils.text import clean
from utils.net.http import fetch
import utils.net.http as http

要点:

  • Python 3.3+ 支持命名空间包(可无 __init__.py),但常规项目仍建议保留它,可在其中做包级初始化和 __all__ 导出声明;

  • 绝对导入(从项目根写全路径)优先;相对导入 from . import text 只在包内部使用;

  • 目录结构即命名空间,避免单层堆几十个模块。

7.3 __name__ == "__main__":模块既能复用又能直接运行

__name__ 是模块的内置属性:

  • 被导入时:__name__ 等于模块名(如 "mymath");

  • 被直接运行时(python mymath.py):等于 "__main__"。

因此标准写法:

def circle_area(r):
    return PI * r ** 2

if __name__ == "__main__":      # 只有直接运行才执行下面的代码
    print(circle_area(2))       # 放测试/演示代码

没有这层保护时,直接运行的模块里 print("mymath 模块被加载了") 会在每次被导入时执行——这就是为什么入口代码必须包在 if __name__ == "__main__": 里。

7.4 导入搜索路径

导入时 Python 按以下顺序查找(sys.path 列表):

  1. 脚本所在目录(或当前目录);

  2. PYTHONPATH 环境变量中的目录;

  3. 标准库目录;

  4. site-packages(第三方包安装位置)。

import sys
sys.path       # 查看实际搜索路径

同名遮蔽陷阱:如果你给自己的文件起名 random.py、json.py,它会遮蔽标准库,导致诡异报错——别用标准库名命名自己的模块。

7.5 标准库速览(内置电池)

Python 的哲学是 "batteries included",常用标准库:

模块用途一行示例
math数学函数math.sqrt(2), math.pi
random随机数random.randint(1, 6)
datetime日期时间datetime.now(), date.today()
os / os.path操作系统接口os.listdir(".")
pathlib现代路径操作(推荐)Path("a/b.txt").read_text()
sys解释器与系统sys.argv, sys.path
jsonJSON 编解码json.dumps(obj), json.load(f)
re正则表达式re.findall(r"\d+", s)
collections增强容器Counter, defaultdict, deque
itertools迭代工具itertools.chain, product
functools函数工具functools.cache, partial
csvCSV 读写csv.reader(f)
shutil高级文件操作shutil.copy(src, dst)
subprocess运行外部命令subprocess.run(["ls", "-l"])
logging日志(别用 print 调试生产代码)logging.info("...")
unittest / doctest测试见第 10 章

两个高频示例

# pathlib —— 跨平台路径,比 os.path 好用得多
from pathlib import Path
p = Path("data") / "config.json"   # 用 / 拼路径
p.exists()
text = p.read_text(encoding="utf-8")
for f in Path(".").glob("*.py"):   # 目录遍历
    print(f)

# collections.Counter —— 计数神器
from collections import Counter
Counter("mississippi").most_common(2)
# [('i', 4), ('s', 4)]

7.6 第三方包管理

pip install requests           # 安装
pip install "requests>=2.31"   # 版本约束
pip install -U requests        # 升级
pip uninstall requests         # 卸载
pip show requests              # 查看包信息

实践规范:

  • 虚拟环境 + requirements.txt 锁定依赖(见第 1 章);

  • 大项目可迁移到更现代的工具:Poetry、uv、PDM(自动管理虚拟环境和锁文件);

  • 找包去 https://pypi.org,看质量和维护状态再引入。

7.7 创建可分发的包(概念)

一个可发布的项目通常长这样:

mypkg/
├── pyproject.toml        # 元数据与构建配置(现代标准)
├── src/
│   └── mypkg/
│       ├── __init__.py
│       └── core.py
└── tests/

pyproject.toml 是 Python 官方现行标准(取代 setup.py),声明名称、版本、依赖、构建后端。发布到 PyPI 用 python -m build + twine upload。初学阶段了解结构即可。

7.8 本章小结

  • 模块 = 文件,包 = 目录;import x 与 from x import y 按需选择;

  • 入口代码包在 if __name__ == "__main__": 里;

  • 别用标准库名给文件命名;

  • 标准库先找一遍再装第三方包;pathlib、collections 值得最先掌握。

下一章:异常处理与调试。

Python3 基础知识 / 第 7 章 模块、包与导入系统 0 字 0 行 cosolar
2026-09-17T11:10:47.732861135Z 2026-09-17T11:25:54.604202448Z