本文目录
标准库体量很大,没人能背下全部 API。实用策略是:先按问题找模块——路径操作用什么、配置 JSON 用什么、简单数据类怎么声明——再记每组里两三句典型语法。下面四块在日常脚本和小服务里出现频率高,且彼此独立;其余模块用到时再查 官方库索引 即可。
和第三方库的分界很简单:import json 装好解释器就有;import httpx 得 pip。标准库的设计偏「积木」——单模块解决一类问题,很少帮你搭完整应用框架。
pathlib:路径当对象
pathlib 用 Path 对象表示文件系统路径,比字符串拼接 / 更清晰,跨平台也更稳:
from pathlib import Path
root = Path("data")
cfg = root / "config.json"
if cfg.is_file():
text = cfg.read_text(encoding="utf-8")
print(len(text))
for py in root.glob("**/*.py"):
print(py.name)/`` 运算符拼接子路径;read_text/write_text 封装常见读写;mkdir(parents=True, exist_ok=True) 一次创建多级目录。需要与旧代码对接时,str(path)或path.as_posix()转成字符串;新代码里尽量留在Path上操作,少在os.path.join与Path` 之间来回 cast。
父目录、后缀、stem 都是属性:path.suffix 得 .json,path.stem 得不含后缀的文件名。批量重命名、按扩展名过滤,用 iterdir() 加列表推导往往几行写完。
json:文本与 Python 对象互转
json 处理 JSON 文本与 dict / list / str / int / float / bool / None 的对应:
import json
from pathlib import Path
payload: dict[str, list[int]] = {"ids": [1, 2, 3]}
raw = json.dumps(payload, ensure_ascii=False, indent=2)
Path("out.json").write_text(raw, encoding="utf-8")
loaded = json.loads(Path("out.json").read_text(encoding="utf-8"))
print(loaded["ids"]) # [1, 2, 3]dumps / loads 在内存字符串上操作;大文件可用 json.load(fp) / json.dump(obj, fp) 流式读写。JSON 不支持 datetime、set、bytes 等,需要自定义 default 回调,或先转成可序列化结构(如 ISO 格式字符串、list)。
from datetime import datetime
def default(o: object) -> str:
if isinstance(o, datetime):
return o.isoformat()
raise TypeError(type(o))
blob = json.dumps({"at": datetime.now()}, default=default)解析不可信输入时,别对超大嵌套深度不设限——必要时用 json.loads(s, parse_constant=...) 等参数,或换更严格的格式(如 schema 校验层)。
dataclasses:少写样板的数据类
字段多、只存数据的类,用 dataclasses 自动生成 __init__、__repr__ 等:
from dataclasses import dataclass, field
@dataclass(slots=True)
class Point:
x: float
y: float
@dataclass
class Bag:
items: list[str] = field(default_factory=list)
tag: str = "default"
p = Point(1.0, 2.0)
print(p) # Point(x=1.0, y=2.0)可变默认值(空 list、空 dict)必须用 field(default_factory=list),不能写 items: list[str] = [],否则所有实例共享同一列表——这是 Python 默认参数的经典坑,dataclass 同样适用。
slots=True(3.10+)减少每个实例的 __dict__,属性集合固定,适合大量小对象。需要不可变记录时,加 frozen=True,字段赋值会触发异常。要与类型检查配合,字段注解照常写;复杂校验仍可在 __post_init__ 里做,或迁移到 pydantic。
collections:内置容器不够用时的补丁
collections 提供几种语义明确的专用容器:
from collections import Counter, defaultdict, deque
words = ["a", "b", "a", "c", "a"]
print(Counter(words)) # Counter({'a': 3, 'b': 1, 'c': 1})
by_len: defaultdict[int, list[str]] = defaultdict(list)
for w in words:
by_len[len(w)].append(w)
q: deque[str] = deque(maxlen=3)
q.extend(["x", "y", "z", "w"])
print(list(q)) # ['y', 'z', 'w']Counter 做频次统计,支持 most_common(n);defaultdict 在缺键时自动建默认值,适合分组聚合;deque 两端 O(1) 进出,适合队列、BFS、固定长度滑动窗口。
还有 namedtuple(轻量只读记录,字段用名字访问)、ChainMap(多层 dict 合并查找,配置覆盖场景)、OrderedDict(3.7+ 普通 dict 也保插入序,新代码很少必选)。读模块文档时,先看「Which is appropriate?」类说明,比从 API 字母表开背高效。
怎么查、怎么组合
四个模块经常在同一条小流水线里出现:Path 找文件 → json 读配置 → dataclass 承载解析结果 → Counter / defaultdict 做汇总。写新功能前在文档里搜关键词(如 "pathlib recursive"、"dataclass frozen"),通常能避免重复造轮子。
标准库函数多数无网络副作用、无全局状态,适合脚本和测试。需要 HTTP 客户端、ORM、异步框架时再引第三方——但路径、JSON、简单数据结构这三类需求,仍建议默认先在 stdlib 里找答案,依赖树会干净很多。
与容器内置类型的分工
上一篇讲过 list / dict / set 的语义;collections 是在此之上补「专用场景」:Counter 像带频次的 dict,deque 像两端快的 list。不要为用 Counter 而 Counter——若只是普通计数 dict 够用,保持简单;遇到 most_common、算术合并(c1 + c2)再用专用类型。
dataclasses 与手写 class 的分界:字段少、无复杂继承、主要存数据 → dataclass;需要自定义元类、复杂描述符、多重继承布局 → 普通 class。dataclass 生成的 __eq__ 默认比字段,适合值对象;要按身份比,需自己控制或使用 object 语义。
读文档的习惯
标准库文档每个模块开头通常有 Overview 和 Examples。优先读这两段,再扫函数列表。遇到 deprecate 提示(如旧式 % 格式化 vs str.format / f-string)时,跟文档推荐的新写法走,减少以后迁移成本。
下面是一条常见的小流水线,四模块串在一起:
from collections import Counter
from dataclasses import dataclass
from pathlib import Path
import json
@dataclass
class LogEntry:
level: str
msg: str
def summarize(path: Path) -> Counter[str]:
rows: list[LogEntry] = [
LogEntry(**item) for item in json.loads(path.read_text(encoding="utf-8"))
]
return Counter(e.level for e in rows)小结
pathlib 管路径对象;json 管 JSON 与内置类型的互转;dataclasses 管声明式数据容器;collections 在计数、分组、队列等场景补专用结构。标准库随解释器安装,import 即可——记典型语法、会查文档,比背 API 表更符合日常开发节奏。
argparse、logging、datetime:按需第三梯队
本篇聚焦四块最高频积木;下列三个模块几乎每个稍大的脚本都会碰到,同样值得知道「去哪查」:
argparse 解析命令行参数,替代手写 sys.argv:
import argparse
parser = argparse.ArgumentParser(description="demo")
parser.add_argument("name")
parser.add_argument("--verbose", action="store_true")
args = parser.parse_args()
print(args.name, args.verbose)logging 分级打日志,比到处 print 易过滤、易重定向:
import logging
logging.basicConfig(level=logging.INFO)
log = logging.getLogger(__name__)
log.info("started")datetime 处理时间点与时区(标准库还有 zoneinfo 管 IANA 时区)。JSON 序列化 datetime 时要自己转成字符串——又回到 json 模块的 default 回调。
三者都不试图替代 Web 框架或配置中心;脚本、批任务、小型 CLI 里足够。
何时仍然引第三方
标准库 deliberate 地「少而稳」:HTTP 客户端没有 requests/httpx 那么顺手,验证 JSON schema 没有 jsonschema/pydantic 那么完整,异步 HTTP 更在 asyncio + 第三方生态里。判断顺序可以是:stdlib 能否在十行内解决 → 能否接受文档里的局限 → 再 pip。这样 requirements.txt 不会无限膨胀,你也更熟悉「不装包能走多远」。
维护老项目时,常见 stdlib 替代迁移:os.path → pathlib;% 格式化 → f-string;手写类存数据 → dataclasses。迁移不必一次完成,触到的文件顺手改,长期读代码更轻松。
错误处理与 I/O 仍多在 stdlib
读 JSON 文件时,pathlib 与 json 组合之外,还要记得 encoding="utf-8"——Windows 默认编码与 Linux 不同,不显式指定会在部署环境切换时踩坑。写文件可用 Path.write_text / read_text,大文件用 open 配合 json.load 流式读。
collections.Counter 做词频、日志级别统计时,减法与交集也有定义(c1 & c2 取 min 计数),适合「两个 multiset 重叠部分」一类小题;不懂语义就退回普通 dict 手动累加,等真遇到需求再查文档。
标准库单元测试 unittest 与 doctest 也在stdlib里;多数新项目选 pytest(第三方),但读老代码或标准库源码时不至于陌生。知道「测试框架也在库索引里有一节」,查文档时少一层神秘。
把 help(json.dumps) 或 REPL 里的 dir(Path) 当作探索入口,比收藏博客清单更抗过期——API 细节会变,但「pathlib 管路径、json 管序列化、dataclasses 管数据形状、collections 补专用容器」这四条主线会留很久。
写脚本时可以先问:路径是否 Path、配置是否 json、中间结构是否 dataclass、聚合是否 Counter/defaultdict——四个问题里有两个答「是」,就值得打开对应文档而不是立刻 pip search。
pathlib 与 json 常成对出现读写配置文件;dataclasses 把 JSON 对象转成有字段名的值;collections 在统计与分组层收尾。四条线覆盖大量「小工具脚本」需求,仍不够时再查 shutil、tempfile、subprocess 等相邻模块——仍在标准库,不必先开浏览器找 wheel。
官方文档按主题分章,比搜索引擎结果更可信。记住模块名 + 典型一句 import,需要细节时 help() 或读 docstring 首段,比收藏过期的博客速查表更省心。
collections.Counter 支持 most_common(k) 取前 k 个高频项;dataclasses.asdict 把实例转回 dict 方便再 json.dumps。这些小组合在日志分析、配置迁移里反复出现,值得练成肌肉记忆。
Path.home()、Path.cwd() 区分用户目录与当前工作目录;脚本里相对路径应基于配置文件或 CLI 参数解析,而不是隐式依赖 shell 的 cwd。标准库刻意保持中立、少魔法,读文档时看到 deprecated 别名就跟随迁移指引换到新 API,以后升级 Python 小版本更平滑。
复习四模块分工:pathlib 解决「路径在哪」;json 解决「文本与对象怎么互转」;dataclasses 解决「结构化数据怎么少写样板」;collections 解决「默认 dict/list 语义不够贴切」。四个问题对齐了,再去查官方文档的函数列表,比从博客抄片段更不易漏参数。
json.loads 解析不可信输入时注意异常处理;dataclass 字段顺序在 3.10+ 可与关键字参数规则配合。标准库示例短、依赖少,适合放进单元测试里当 fixture 生成器。这是本篇收束。下一篇讲第三方与 pip:边界在于「解释器自带够不够」,不够时带着 venv 与 requirements 扩边界。