Python 标准库全解析

Python 标准库是随解释器一起安装的模块集合,覆盖了文件系统、网络、编码、时间、并发、测试等日常开发的主要需求。它不依赖任何第三方包,因此也被视为 Python”开箱即用”能力的核心。

标准库的范围比想象中大——pydoc 的模块列表有 200 多个条目,其中 __future__、_thread 这类属于内部实现,不算对外 API。下面按用途挑出实际项目里用得最多的模块。

一个前置判断:标准库解决的是”通用能力”,不是”特定领域需求”。需要 HTTP 客户端、日期时间处理、JSON 解析这类事,先看标准库能不能满足;需要 ORM、深度学习框架、Web 框架时才引入第三方包。这个顺序能显著减少依赖数量。

文件与目录操作

pathlib

pathlib(3.4+)是现在处理路径的默认选择,它把路径变成对象,替代了 os.path 的字符串拼接。

from pathlib import Path

path = Path("data") / "input.txt"
print(path.name)        # input.txt
print(path.suffix)      # .txt
print(path.parent)      # data
print(path.exists())    # False(当前目录下没有这个文件)

判断和查找:

from pathlib import Path

print(Path(".").exists())                   # True

for file in Path(".").glob("*.py"):
    print(file.name)

print(list(Path(".").rglob("*.md"))[:3])    # 递归查找

读写操作:

from pathlib import Path

target = Path("output.txt")
target.write_text("hello", encoding="utf-8")
print(target.read_text(encoding="utf-8"))   # hello
target.unlink()                            # 清理,避免污染工作目录

遍历目录树:

from pathlib import Path

for item in list(Path(".").iterdir())[:5]:
    kind = "目录" if item.is_dir() else "文件"
    print(f"{kind}: {item.name}")

Path(__file__) 这个写法值得单独提:它取当前脚本文件所在目录,在写”配置和脚本放一起”的小工具时很常见。

from pathlib import Path

base = Path(__file__).resolve().parent
config_path = base / "config.toml"
print(config_path)

注意 __file__ 前后各两个下划线,是 Python 内置变量,不是关键字。在交互式环境里它不存在,所以调试这段代码时要用 Path(".") 替代。

os

os 提供与操作系统直接交互的接口。凡是 pathlib 能做的,优先用 pathlib;os 剩下的独有价值主要是进程、环境变量和系统调用。

import os

print(os.getcwd())              # 当前工作目录
print(os.environ.get("HOME"))   # 读环境变量
print(os.listdir("."))          # 列出目录内容
os.makedirs("output/logs", exist_ok=True)   # 递归创建目录

运行外部命令:

import subprocess

result = subprocess.run(
    ["python", "--version"],
    capture_output=True,
    text=True,
    check=True,
)
print(result.stdout.strip())

subprocess.run 传列表而不是字符串,可以避免 shell 注入。如果确实需要 shell 语法,用 shell=True,但此时必须自行校验输入。

环境变量的读写:

import os

os.environ["APP_ENV"] = "production"
print(os.getenv("APP_ENV"))     # production

shutil

shutil 负责复制、移动、删除这类文件级操作——os 只管元数据和路径。

import shutil
import tempfile
from pathlib import Path

with tempfile.TemporaryDirectory() as tmp:
    root = Path(tmp)
    (root / "source.txt").write_text("hello", encoding="utf-8")
    (root / "source_dir").mkdir()
    (root / "source_dir" / "a.txt").write_text("a", encoding="utf-8")

    shutil.copy(root / "source.txt", root / "target.txt")
    shutil.copytree(root / "source_dir", root / "target_dir")   # 递归复制目录
    shutil.make_archive(str(root / "backup"), "zip", root / "source_dir")

    print(sorted(p.name for p in root.iterdir()))

shutil.rmtree 没有确认机制,路径写错就是数据丢失。可以先 shutil.copytree 备份再删,或者用 shutil.disk_usage 检查空间。

网络与数据格式

json

json 是最常用的数据交换格式,json.dumps 序列化、json.loads 反序列化。

import json

data = {"name": "Alice", "age": 18, "tags": ["a", "b"]}
text = json.dumps(data, ensure_ascii=False, indent=2)
print(text)

obj = json.loads(text)
print(obj["name"])     # Alice

ensure_ascii=False 让中文以原样输出而不是 \uXXXX 转义,可读性好很多。indent=2 用于日志和调试输出。

json.dump/json.load 直接操作文件:

import json

data = {"name": "Alice", "age": 18}

with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

with open("data.json", "r", encoding="utf-8") as f:
    obj = json.load(f)
print(obj["name"])     # Alice

需要处理非标准 JSON(比如尾随逗号、单引号)时,json 的严格模式会报错,这时可以用 ast.literal_eval 兜底,但它只认字面量。

csv

csv 模块处理逗号分隔文件,正确处理引号、内嵌逗号和换行。

import csv

with open("data.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(["姓名", "年龄"])
    writer.writerow(["Alice", 18])

with open("data.csv", "r", newline="", encoding="utf-8") as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

newline="" 是官方文档明确要求的写法——不设的话在 Windows 上会出现空行。

字典形式更常用:

import csv

with open("data.csv", "r", newline="", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row["姓名"], row["年龄"])

urllib 与 http

标准库能发 HTTP 请求,只是 API 比较底层。

from urllib.request import urlopen

with urlopen("https://www.python.org") as resp:
    print(resp.getcode())                       # 200
    print(resp.read(100).decode("utf-8"))

urlopen 默认会跟随重定向、设置 User-Agent 之外的东西较少。实际项目里处理 JSON API 通常要自己加请求头:

from urllib.request import Request, urlopen
import json

req = Request(
    "https://api.example.com/items",
    headers={"User-Agent": "my-script/1.0", "Accept": "application/json"},
)
with urlopen(req, timeout=10) as resp:
    payload = json.loads(resp.read().decode("utf-8"))

timeout 必须显式指定,否则网络异常时可能一直挂着。

http.server 可以起一个本地测试服务器:

from http.server import BaseHTTPRequestHandler, HTTPServer

class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        body = b"Hello HTTP Server"
        self.send_response(200)
        self.send_header("Content-Type", "text/plain")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

if __name__ == "__main__":
    with HTTPServer(("localhost", 8000), MyHandler) as httpd:
        print("Serving on http://localhost:8000")
        httpd.serve_forever()

它适合本地调试和测试,不要直接暴露到公网——没有并发处理,也没有安全防护。

socket

socket 是更底层的接口,需要自定义协议时用。

import socket

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(("localhost", 8080))
server.listen(5)

with server:
    conn, addr = server.accept()
    with conn:
        data = conn.recv(1024)
        print("收到:", data.decode("utf-8"))
        conn.send(b"Hello Client")

with 的写法保证 socket 一定会被关闭,异常路径下也不会泄漏文件描述符。

email 与 smtplib

发邮件需要两者配合:email 构造消息,smtplib 负责投递。

import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg["Subject"] = "测试邮件"
msg["From"] = "sender@example.com"
msg["To"] = "receiver@example.com"
msg.set_content("这是正文内容")

with smtplib.SMTP("smtp.example.com", 587, timeout=30) as server:
    server.starttls()
    server.login("sender@example.com", "password")
    server.send_message(msg)

现代写法用 EmailMessage,比老的 MIMEText 简洁。starttls() 是必须的——不加密的话账号密码是明文传输的。

文本与数据处理

re

re 提供正则表达式。

import re

pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
email = "test@example.com"
print(re.match(pattern, email) is not None)    # True

re.match 只从字符串开头匹配,re.search 在全文里找。用 re.fullmatch 要求整体匹配:

import re

print(re.fullmatch(r"\d{4}-\d{2}-\d{2}", "2026-10-24"))   # True
print(re.match(r"\d+", "abc123"))                          # None,开头不匹配
print(re.search(r"\d+", "abc123").group())                 # 123

分组和替换:

import re

text = "2026-10-24 和 2026-01-01"
print(re.findall(r"\d{4}-\d{2}-\d{2}", text))    # ['2026-10-24', '2026-01-01']
print(re.sub(r"\d{4}", "2025", text))

编译后的正则可以复用,大数据量时更快:

import re

pattern = re.compile(r"\d+")
print(pattern.findall("a1b22c333"))     # ['1', '22', '333']

collections 与 itertools

collections 提供容器类型,itertools 提供惰性迭代工具。

from collections import Counter, defaultdict, deque

print(Counter("aabbbc"))                    # Counter({'b': 3, 'a': 2, 'c': 1})

groups = defaultdict(list)
groups["x"].append(1)
print(dict(groups))                          # {'x': [1]}

queue = deque([1, 2, 3])
queue.append(4)
print(queue.popleft())                       # 1

defaultdict(list) 比 setdefault 更简洁,也不会每次都白建一个空列表。

itertools 的组合函数是数据处理常用工具:

import itertools

print(list(itertools.product([1, 2], ["a", "b"])))
1. [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

print(list(itertools.combinations([1, 2, 3], 2)))   # [(1, 2), (1, 3), (2, 3)]
print(list(itertools.permutations([1, 2], 2)))       # [(1, 2), (2, 1)]

print(list(itertools.islice(range(10), 3, 6)))       # [3, 4, 5]

itertools.count() 是无限迭代器,配合 islice 取有限段:

import itertools

print(list(itertools.islice(itertools.count(10, 2), 4)))   # [10, 12, 14, 16]

hashlib

hashlib 提供 MD5、SHA-1、SHA-256、SHA-512 等哈希算法。

import hashlib

data = b"hello world"
print(hashlib.sha256(data).hexdigest())
print(hashlib.md5(data).hexdigest())

增量哈希适合处理大文件,不必一次读进内存:

import hashlib
import tempfile
from pathlib import Path

with tempfile.TemporaryDirectory() as tmp:
    bigfile = Path(tmp) / "bigfile.bin"
    bigfile.write_bytes(b"x" * 200000)

    digest = hashlib.sha256()
    with bigfile.open("rb") as f:
        for chunk in iter(lambda: f.read(65536), b""):
            digest.update(chunk)
    print(digest.hexdigest())

安全提醒:MD5 和 SHA-1 已被证明存在碰撞漏洞,不能用于签名或完整性校验。密码存储要用 hashlib.pbkdf2_hmac 或 argon2 这类专用方案,而不是直接 sha256(password)——那样会被彩虹表直接反查。

base64 与 struct

import base64

encoded = base64.b64encode(b"hello")
print(encoded)                    # b'aGVsbG8='
print(base64.b64decode(encoded))   # b'hello'

base64 是编码不是加密,任何人都能解码,别用它保护机密。

系统与运行时

sys

sys 提供解释器层面的信息和控制。

import sys

print(sys.argv)            # 命令行参数,argv[0] 是脚本名
print(sys.version)         # 版本信息
print(sys.platform)        # 平台标识
print(sys.executable)      # 解释器路径
print(sys.path)            # 模块搜索路径

sys.exit() 是脚本的正确退出方式,退出码 0 表示成功:

import sys

if len(sys.argv) < 2:
    print("用法:script.py <参数>")
    sys.exit(1)

print("收到参数:", sys.argv[1])

platform 与 tempfile

import platform

print(platform.system())        # Linux / Windows / Darwin
print(platform.machine())       # x86_64
print(platform.python_version())

tempfile 处理临时文件,比自己拼 /tmp/xxx 可靠——它会自动清理并避免名字冲突。

import tempfile
from pathlib import Path

with tempfile.TemporaryDirectory() as tmp:
    p = Path(tmp) / "scratch.txt"
    p.write_text("data", encoding="utf-8")
    print(p.exists())     # True
1. 离开 with 块,目录已自动删除

单文件用 NamedTemporaryFile:

import tempfile

with tempfile.NamedTemporaryFile("w", encoding="utf-8", delete=False) as f:
    f.write("hello")
    path = f.name
print(path)

argparse

命令行参数解析,argparse 是标准方案。

import argparse

parser = argparse.ArgumentParser(description="示例工具")
parser.add_argument("name", help="用户名")
parser.add_argument("--count", type=int, default=1, help="重复次数")
parser.add_argument("--verbose", action="store_true", help="输出详情")
args = parser.parse_args()

print(args.name, args.count, args.verbose)

type=int 让参数自动转成整数,转换失败时 argparse 会给出友好报错并退出——比手动 int(argv[1]) 加 try/except 干净得多。

subprocess

import subprocess

out = subprocess.run(
    ["echo", "hello"],
    capture_output=True,
    text=True,
    check=True,
)
print(out.stdout.strip())

需要管道串联时用 Popen:

import subprocess

proc = subprocess.Popen(
    ["python", "-c", "print('from child')"],
    stdout=subprocess.PIPE,
    text=True,
)
stdout, _ = proc.communicate()
print(stdout.strip())

时间与日期

datetime

datetime 是日期时间处理的主力模块。

from datetime import datetime, timedelta, date

now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S"))

future = now + timedelta(days=3)
print(future.date())

birthday = date(1990, 5, 20)
age = date.today().year - birthday.year
print(age)

时区处理要用 zoneinfo(3.9+),不要自己加减小时:

from datetime import datetime
from zoneinfo import ZoneInfo

shanghai = datetime.now(ZoneInfo("Asia/Shanghai"))
utc = datetime.now(ZoneInfo("UTC"))
print(shanghai, utc)

zoneinfo 依赖系统时区数据库,某些精简容器镜像里没有,需要装 tzdata 包。也可以用固定偏移:

from datetime import datetime, timezone, timedelta

tz = timezone(timedelta(hours=8))
print(datetime.now(tz))

datetime.strptime 解析字符串时间:

from datetime import datetime

dt = datetime.strptime("2026-10-24 15:30:00", "%Y-%m-%d %H:%M:%S")
print(dt.year, dt.month, dt.day)

time

time 是更底层的时间接口。

import time

timestamp = time.time()                       # Unix 时间戳(浮点秒)
print(time.localtime(timestamp))
print(time.strftime("%Y-%m-%d", time.localtime(timestamp)))

monotonic = time.monotonic()                 # 单调递增,不受系统时间调整影响
print(monotonic)

测耗时时用 time.monotonic() 或 time.perf_counter(),不要用 time.time()——后者可能被 NTP 校时往回拨。

calendar

import calendar

print(calendar.isleap(2024))     # True
print(calendar.month(2024, 5))
print(calendar.weekday(2026, 10, 24))    # 5,星期五

zoneinfo 之外的选择

处理”重复的时间”(夏令时回拨)时,标准库的做法是保持 datetime 为带时区的 aware 对象,用 fold 参数消歧:

from datetime import datetime
from zoneinfo import ZoneInfo

dt = datetime(2026, 11, 1, 1, 30, tzinfo=ZoneInfo("America/New_York"), fold=1)
print(dt)

并发与并行

threading

threading 提供线程,适合 I/O 密集型任务。

import threading
import time

def task(name):
    print(f"线程 {name} 开始")
    time.sleep(0.1)
    print(f"线程 {name} 结束")

threads = [threading.Thread(target=task, args=(f"T{i}",)) for i in range(3)]
for t in threads:
    t.start()
for t in threads:
    t.join()

join() 等待线程结束,否则主程序可能在子线程完成前就退出。

线程间共享数据要用锁:

import threading

counter = 0
lock = threading.Lock()

def increment():
    global counter
    for _ in range(1000):
        with lock:
            counter += 1

threads = [threading.Thread(target=increment) for _ in range(4)]
for t in threads:
    t.start()
for t in threads:
    t.join()
print(counter)      # 4000

with lock: 写法比 lock.acquire()/lock.release() 更安全,异常时也会释放。

multiprocessing

multiprocessing 用多进程绕过 GIL,适合 CPU 密集型任务。

from multiprocessing import Process

def calc(num):
    print(f"计算结果:{num * num}")

if __name__ == "__main__":
    processes = [Process(target=calc, args=(i,)) for i in (5, 10)]
    for p in processes:
        p.start()
    for p in processes:
        p.join()

if __name__ == "__main__": 这层保护必须写。Windows 和 macOS(spawn 启动方式)会重新导入主模块,没有保护会导致进程无限创建。

asyncio

asyncio 是异步 I/O 框架,单线程内通过事件循环调度协程。

import asyncio

async def fetch(name):
    await asyncio.sleep(1)      # 模拟 I/O 等待
    return f"{name} 的结果"

async def main():
    results = await asyncio.gather(fetch("A"), fetch("B"), fetch("C"))
    for r in results:
        print(r)

asyncio.run(main())

asyncio.gather 并发执行多个协程,总耗时约等于最慢的那个,而不是三者之和。

asyncio.to_thread(3.9+)可以把同步阻塞函数丢到线程池:

import asyncio
import time

def blocking():
    time.sleep(0.5)
    return "done"

async def main():
    result = await asyncio.to_thread(blocking)
    print(result)

asyncio.run(main())

queue

queue 提供线程安全的队列,用于生产消费模型。

import queue
import threading

q = queue.Queue(maxsize=5)

def producer():
    for i in range(10):
        q.put(i)

def consumer():
    while True:
        item = q.get()
        print("消费:", item)
        q.task_done()   # 每次 get 对应一次 task_done

producer_t = threading.Thread(target=producer)
consumer_t = threading.Thread(target=consumer, daemon=True)
producer_t.start()
consumer_t.start()
producer_t.join()   # 等生产者放完
q.join()            # 等所有任务被消费处理完,然后正常退出

注意 task_done() 要和 get() 配对调用,否则 q.join() 会一直等。

测试与调试

unittest

标准库的单元测试框架,不依赖 pytest。

import unittest

class TestAdd(unittest.TestCase):
    def test_add(self):
        self.assertEqual(1 + 2, 3)

    def test_divide(self):
        with self.assertRaises(ZeroDivisionError):
            1 / 0

if __name__ == "__main__":
    unittest.main()

doctest

把测试写在文档字符串里,文档和测试合一。

import doctest

def add(a, b):
    """
    计算两数之和。

    >>> add(1, 2)
    3
    """
    return a + b

if __name__ == "__main__":
    doctest.testmod()

doctest.testmod() 会在文档里找 >>> 开头的示例并执行,输出不符就报错。适合给纯函数写示例。

timeit

测量代码片段的执行时间。

import timeit

t = timeit.timeit("[i * 2 for i in range(1000)]", number=10000)
print(f"耗时 {t:.4f} 秒")

timeit 会自动排除启动开销,测的是纯执行时间,比手写 time.time() 前后相减准确。

pdb

内置调试器。

import pdb

def func(x):
    pdb.set_trace()      # 在这里停下
    return x * 2

func(5)

breakpoint()(3.7+)是更简洁的等价写法。

其他实用模块

tkinter

GUI 工具包,标准库自带。

import tkinter as tk

root = tk.Tk()
root.title("简单 GUI")

label = tk.Label(root, text="你好")
label.pack()

button = tk.Button(root, text="点击我", command=lambda: print("按钮被点击"))
button.pack()

root.mainloop()

在无图形环境的服务器上会报 TclError,这是环境问题不是代码问题。

secrets

生成密码和随机令牌的安全模块,应该优先于 random。

import secrets

token = secrets.token_urlsafe(32)
print(token)

print(secrets.compare_digest("abc", "abc"))   # True,常量时间比较

statistics

import statistics

data = [1, 2, 3, 4, 100]
print(statistics.mean(data))        # 22
print(statistics.median(data))      # 3
print(statistics.stdev(data))       # 43.63

configparser 与 tomllib

INI 格式用 configparser:

import configparser

config = configparser.ConfigParser()
config["Database"] = {"host": "localhost", "port": "3306"}
config.read("config.ini", encoding="utf-8")
print(config.get("Database", "host"))     # localhost

TOML 格式读用 tomllib(3.11+,只读),写用第三方 tomli-w:

import tomllib

with open("config.toml", "rb") as f:
    config = tomllib.load(f)
print(config)

注意 tomllib.load 要用 "rb" 二进制模式打开。

使用注意事项

  • 先确认标准库能不能满足。只有确实需要特定领域能力时才加第三方依赖。
  • 按需导入具体名字。from pathlib import Path 比 import pathlib 更快,也更明确用到哪个。
  • 注意版本要求。zoneinfo 需要 3.9+,tomllib 需要 3.11+,asyncio.to_thread 需要 3.9+。写库时先定好支持的最低版本。
  • 安全相关的用专用模块。密码哈希用 hashlib.pbkdf2_hmac,令牌生成用 secrets,URL 解析用 urllib.parse 而不是手写正则。
  • pickle 不安全。反序列化不可信来源的 pickle 数据等于执行任意代码,跨进程传输用 JSON。
  • 优先读官方文档。标准库细节多,help() 和 docs.python.org 是最准的来源。

相关文档

暂无评论

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇