K 的一隅

Python Python 语言核心

先会找再会用:标准库里几组高频工具

标准库随解释器安装;pathlib 管路径、json 管序列化、dataclasses 管数据容器、collections 补常用结构——各记典型用法即可。

8 分钟阅读 更新于 2026-07-28
本文目录

标准库体量很大,没人能背下全部 API。实用策略是:先按问题找模块——路径操作用什么、配置 JSON 用什么、简单数据类怎么声明——再记每组里两三句典型语法。下面四块在日常脚本和小服务里出现频率高,且彼此独立;其余模块用到时再查 官方库索引 即可。

和第三方库的分界很简单:import json 装好解释器就有;import httpx 得 pip。标准库的设计偏「积木」——单模块解决一类问题,很少帮你搭完整应用框架。

pathlib:路径当对象

pathlibPath 对象表示文件系统路径,比字符串拼接 / 更清晰,跨平台也更稳:

python
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.joinPath` 之间来回 cast。

父目录、后缀、stem 都是属性:path.suffix.jsonpath.stem 得不含后缀的文件名。批量重命名、按扩展名过滤,用 iterdir() 加列表推导往往几行写完。

json:文本与 Python 对象互转

json 处理 JSON 文本与 dict / list / str / int / float / bool / None 的对应:

python
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 不支持 datetimesetbytes 等,需要自定义 default 回调,或先转成可序列化结构(如 ISO 格式字符串、list)。

python
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__ 等:

python
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 提供几种语义明确的专用容器:

python
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 语义。

读文档的习惯

标准库文档每个模块开头通常有 OverviewExamples。优先读这两段,再扫函数列表。遇到 deprecate 提示(如旧式 % 格式化 vs str.format / f-string)时,跟文档推荐的新写法走,减少以后迁移成本。

下面是一条常见的小流水线,四模块串在一起:

python
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

python
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 易过滤、易重定向:

python
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.pathpathlib% 格式化 → f-string;手写类存数据 → dataclasses。迁移不必一次完成,触到的文件顺手改,长期读代码更轻松。

错误处理与 I/O 仍多在 stdlib

读 JSON 文件时,pathlibjson 组合之外,还要记得 encoding="utf-8"——Windows 默认编码与 Linux 不同,不显式指定会在部署环境切换时踩坑。写文件可用 Path.write_text / read_text,大文件用 open 配合 json.load 流式读。

collections.Counter 做词频、日志级别统计时,减法与交集也有定义(c1 & c2 取 min 计数),适合「两个 multiset 重叠部分」一类小题;不懂语义就退回普通 dict 手动累加,等真遇到需求再查文档。

标准库单元测试 unittestdoctest 也在stdlib里;多数新项目选 pytest(第三方),但读老代码或标准库源码时不至于陌生。知道「测试框架也在库索引里有一节」,查文档时少一层神秘。

help(json.dumps) 或 REPL 里的 dir(Path) 当作探索入口,比收藏博客清单更抗过期——API 细节会变,但「pathlib 管路径、json 管序列化、dataclasses 管数据形状、collections 补专用容器」这四条主线会留很久。

写脚本时可以先问:路径是否 Path、配置是否 json、中间结构是否 dataclass、聚合是否 Counter/defaultdict——四个问题里有两个答「是」,就值得打开对应文档而不是立刻 pip search

pathlibjson 常成对出现读写配置文件;dataclasses 把 JSON 对象转成有字段名的值;collections 在统计与分组层收尾。四条线覆盖大量「小工具脚本」需求,仍不够时再查 shutiltempfilesubprocess 等相邻模块——仍在标准库,不必先开浏览器找 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 扩边界。