前言
标准库(standard library)是随 Python 一起安装、不需要 pip 就能 import 的那一大堆模块。官方常说 Python "batteries included"(自带电池),指的就是标准库覆盖面极广:文件操作、日期时间、正则、JSON、CSV、SQLite、网络、并发、加密哈希、单元测试全都有。
一个很常见的误区是:遇到需求第一反应去搜第三方库。实际上很多场景标准库就够了------处理 JSON 用 json 而不是手写解析,做命令行参数用 argparse 而不是自己切 sys.argv,算统计量用 statistics 而不是装 numpy。第三方库有它的位置(数据分析、Web 框架、科学计算),但"先看标准库"能省掉大量依赖管理成本。
真正的问题往往不是"没有模块",而是"不记得有没有、存在哪个模块里、参数怎么传"。所以本文分两部分:先按用途给出一张常用模块地图,再重点讲怎么查 ------help()、dir()、pydoc、以及程序里怎么列出所有标准库模块名。示例基于 Python 3.8+,用到新版本特性的地方单独标注。
一、常用标准库模块地图
下面按用途归类。同一件事常有多个模块可选,括号里注明更现代的替代或需要使用的新版本。
| 用途 | 模块 | 代表内容 |
|---|
|--------|-----------------------|---------------------------------------------|
| 系统与解释器 | sys、os、platform | sys.argv、os.environ、platform.system() |
|-------|------------------------------------------------|----------------------------------------------------|
| 路径与文件 | pathlib、os.path、shutil、glob、tempfile | Path、copy、rmtree、glob、TemporaryDirectory |
|------|------------------------------------|-----------------|
| 文本处理 | re、string、textwrap、difflib | 正则、字符常量、折行、序列比对 |
|------|------------------------------|----------------------------------|
| 日期时间 | datetime、time、zoneinfo | date、datetime、timedelta、时区 |
|------|---------------------------------------|-----------------------------------------|
| 数据格式 | json、csv、configparser、tomllib | 读写 JSON/CSV/INI/TOML(tomllib 需 3.11+) |
|------|----------------------------------------|--------------------------------------|
| 数据结构 | collections、heapq、bisect、array | defaultdict、Counter、deque、堆、二分 |
|-------|------------------------------------|-----------------------------------------|
| 函数式工具 | itertools、functools、operator | groupby、chain、partial、lru_cache |
|-------|----------------------------------------------------|----------------------|
| 数值与统计 | math、statistics、decimal、fractions、random | 数学函数、均值方差、精确小数、分数、随机 |
|-----|--------------------------|--------------|
| 持久化 | sqlite3、pickle、dbm | 嵌入式数据库、对象序列化 |
|----|--------------------------------------------------------------|--------------|
| 并发 | threading、multiprocessing、concurrent.futures、asyncio | 线程、进程、执行器、协程 |
|-------|--------------------------------------------|-------------------|
| 网络与协议 | urllib、http、socket、email、smtplib | 请求、HTTP 工具、套接字、邮件 |
|-------|--------------------------------------------------|------------------------|
| 安全与编码 | hashlib、hmac、secrets、base64、uuid、ssl | 摘要、恒定时间比较、安全随机、编码、UUID |
|--------|--------------------------------|--------------|
| 命令行与日志 | argparse、logging、getpass | 参数解析、日志、隐藏输入 |
|-------|----------------------------------------|-------------------|
| 测试与调试 | unittest、doctest、traceback、pdb | 单元测试、文档测试、异常栈、调试器 |
|--------|--------------------------------------------------|-------------------------|
| 类型与元编程 | typing、dataclasses、enum、abc、contextlib | 类型标注、数据类、枚举、抽象基类、上下文管理器 |
pickle 需要特别提醒:它能反序列化出任意对象,反序列化不可信数据等于允许对方在你的进程里执行代码 ,跨信任边界的数据一律改用 json 等纯数据格式。
二、在程序里查询:help 与 dir
最直接的查询方式是内置的 help() 和 dir()。help() 会打印签名、文档字符串和成员列表;dir() 只列出名字,速度快、适合探索。
python
# 适用于 Python 3.8+
import json
print(dir(json)[:8]) # 看到 dump、dumps、load 等名字
help(json.dumps) # 打印签名与说明
import inspect
print(inspect.signature(json.dumps))
注意 help() 的输出是给"人"看的,格式会随版本变;要在程序里稳定地拿签名,用 inspect.signature() 。签名里的 / 表示其前的参数是仅位置参数,* 表示其后的参数是仅关键字参数。比如 json.dumps(obj, *, skipkeys=False, ensure_ascii=True, ...) ------ 第一个参数是位置的,后面那一堆都得写关键字。
__doc__ 属性也能拿到文档字符串,但格式化不好,不如 help()。
三、命令行查询:pydoc
pydoc 能把文档直接输出到终端,甚至起一个本地网页服务器。
bash
# 查看某个模块的文档
python -m pydoc json
# 按关键词搜索所有模块的摘要行
python -m pydoc -k csv
# 启动本地文档服务器并自动打开浏览器
python -m pydoc -b
# 指定端口启动文档服务器
python -m pydoc -p 1234
-k 很适合"我记得有个模块能干这件事,但想不起叫什么"。注意它是在已安装的所有模块里搜摘要,因此搜索结果可能包含第三方库。
四、列出所有标准库模块名
Python 3.10 起,sys.stdlib_module_names 提供了一个 frozenset,里面是全平台一致的标准库模块名。
python
# 适用于 Python 3.10+
import sys
names = sys.stdlib_module_names
print(len(names))
print("json" in names) # True
# 找出所有以 "csv" 开头的标准库模块
print(sorted(n for n in names if n.startswith("csv")))
官方文档说明它有几个特点:全平台一致 (某些平台上不可用、或构建时被禁用的模块也列在里面);纯 Python 模块、内置模块、冻结模块、扩展模块都算;测试模块被排除;包只列主包名,子包不列(例如有 email,但没有 email.mime)。
如果只想知道哪些模块是"编译进解释器"的,用 sys.builtin_module_names。要判断某个已导入的模块来自标准库还是第三方,可以看它的 __file__ 路径是否落在标准库目录下,但更省事的做法是直接查 sys.stdlib_module_names。
五、一段常用于自检的查询脚本
python
# 适用于 Python 3.10+
import sys
import importlib
import inspect
def probe(modname, attr):
"""打印模块某个成员的存在性、签名与文档首行。"""
try:
mod = importlib.import_module(modname)
except ImportError as e:
print(f"无法导入 {modname}: {e}")
return
obj = getattr(mod, attr, None)
if obj is None:
print(f"{modname} 中没有 {attr}")
return
try:
sig = inspect.signature(obj)
except (TypeError, ValueError):
sig = "(无法获取签名)"
doc = (inspect.getdoc(obj) or "").splitlines()
print(f"{modname}.{attr}{sig}")
print(" ", doc[0] if doc else "(无文档)")
probe("json", "dumps")
probe("pathlib", "Path")
print("stdlib 模块数:", len(sys.stdlib_module_names))
这段代码不依赖任何第三方库,可以当作探索陌生模块的起点。
常见坑点
坑 1:模块名和变量名撞车。
❌
python
import json
json = {"a": 1} # 之后 json.dumps 全废
✅ 模块名(json、csv、random、email)别拿来当变量名;尤其别写 import random 之后又 random = random.choice(xs)。
坑 2:from 模块 import * 污染命名空间。
❌ from os import * 之后 os、sys 里的一堆名字混进本模块,还可能与自己的变量重名。
✅ import os,或用 from os import path, getcwd 这类显式导入。
坑 3:以为标准库都是纯 Python。
❌ 以为 json、socket 这些是纯 Python 实现,能随便读源码改。
✅ 标准库混合了纯 Python、C 扩展和内置模块。要确认来源用 sys.stdlib_module_names 与 sys.builtin_module_names;json 的核心加速是 C 扩展 _json。
坑 4:用 pickle 加载外来数据。
❌ pickle.load(open("下载来的文件", "rb")) ------ pickle 反序列化会执行构造逻辑,不可信数据可能引发任意代码执行。
✅ 跨信任边界一律用 json 等纯数据格式;pickle 只用于自己完全掌控的进程内持久化。
坑 5:忘记标准库版本差异。
❌ 在 3.9 上写 import tomllib(3.11 才有)、用 sys.stdlib_module_names(3.10 才有)。
✅ 需要 TOML 且版本低于 3.11 时用第三方 tomli;需要标准库模块名单时先用 getattr(sys, "stdlib_module_names", None) 做特性探测。
坑 6:读写文件不指定编码。
❌ json.load(open("data.json")) 在 Windows 上按本地编码读,UTF-8 内容乱码。
✅ open("data.json", encoding="utf-8");pathlib 则用 Path("data.json").read_text(encoding="utf-8")。
坑 7:os.path 与 pathlib 混着用。
❌ 一半代码 os.path.join(a, b),另一半 Path(a) / b,字符串与 Path 对象来回转换。
✅ 新代码统一用 pathlib.Path,它在大多数接收路径的 API 上都能直接传。
坑 8:import 模块 写在函数里图省事。
❌ 在一个被高频调用的函数里反复 import json,虽不算错但可读性差、也让人低估依赖。
✅ 模块级统一导入;只在解决循环导入 或加载很重的可选依赖时才在函数内导入,并加注释说明原因。
总结
| 需求 | 先看哪个模块 | 备注 |
|---|
|---------|-----------|-----------------------|
| 路径与目录操作 | pathlib | 新代码优先,取代 os.path 拼接 |
|---------------------|---------------------------------|-------------------------|
| 读写 JSON / CSV / INI | json / csv / configparser | TOML 用 tomllib(3.11+) |
|------|------------|----------------------|
| 日期时间 | datetime | 时区用 zoneinfo(3.9+) |
|------|---------------|---------------------------------|
| 容器增强 | collections | defaultdict、Counter、deque |
|------|-------------------------|-------------------------------|
| 迭代工具 | itertools、functools | chain、groupby、lru_cache |
|-------|------------|-----------------|
| 命令行参数 | argparse | 别手动切 sys.argv |
|----|-----------|----------------|
| 日志 | logging | 别用 print 当日志 |
|------|------------------------------------|-------------------------------|
| 查询文档 | help()、dir()、pydoc、inspect | 命令行用 python -m pydoc -k 关键词 |
掌握"先查标准库、再考虑第三方"的习惯,配合 help()、dir()、python -m pydoc -k 这三把工具,基本可以摆脱"不记得有没有现成模块"的焦虑。要记住的边界只有两条:涉及不可信数据时不要用 pickle ,以及较新的模块(tomllib 3.11、sys.stdlib_module_names 3.10、zoneinfo 3.9)在使用前先确认目标 Python 版本。遇到版本差异,以 Python 官方文档的模块索引和各版本的"更新日志"章节为准,不要采信二手说法。