首页 / 知识库 / 0基础入门-阅读资料 / 0基础-python入门到精通

第 24 章 Python 标准库精选

24.1 collections

deque — 双端队列

from collections import deque

# 两端 O(1) 操作
d = deque([1, 2, 3])
d.appendleft(0)   # deque([0, 1, 2, 3])
d.append(4)        # deque([0, 1, 2, 3, 4])
d.popleft()        # 0
d.pop()            # 4

# 固定长度(自动丢弃旧元素)
history = deque(maxlen=5)
for i in range(10):
    history.append(i)
print(history)  # deque([5, 6, 7, 8, 9], maxlen=5)

# 旋转
d = deque([1, 2, 3, 4, 5])
d.rotate(2)    # deque([4, 5, 1, 2, 3]) — 右旋
d.rotate(-2)   # deque([1, 2, 3, 4, 5]) — 左旋

ChainMap — 链式映射

from collections import ChainMap

defaults = {"color": "red", "size": 10}
user_prefs = {"color": "blue"}
cli_args = {"size": 20}

# 优先级: cli_args > user_prefs > defaults
config = ChainMap(cli_args, user_prefs, defaults)
print(config["color"])  # blue(来自 user_prefs)
print(config["size"])   # 20(来自 cli_args)

# 修改只影响第一个映射
config["new_key"] = "value"
print(cli_args)  # {'size': 20, 'new_key': 'value'}

Counter — 计数器

from collections import Counter

# 计数
words = "the quick brown fox jumps over the lazy dog the fox".split()
c = Counter(words)
print(c.most_common(3))  # [('the', 3), ('fox', 2), ('quick', 1)]

# 运算
c1 = Counter(a=3, b=1)
c2 = Counter(a=1, b=2)
print(c1 + c2)    # Counter({'a': 4, 'b': 3})
print(c1 - c2)    # Counter({'a': 2})
print(c1 & c2)    # Counter({'a': 1, 'b': 1}) — 取最小值
print(c1 | c2)    # Counter({'a': 3, 'b': 2}) — 取最大值

# 统计字符
Counter("abracadabra")  # Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})

defaultdict — 默认值字典

from collections import defaultdict

# 自动初始化
word_groups = defaultdict(list)
for word in ["apple", "banana", "avocado", "blueberry", "cherry"]:
    word_groups[word[0]].append(word)
print(dict(word_groups))
# {'a': ['apple', 'avocado'], 'b': ['banana', 'blueberry'], 'c': ['cherry']}

# 嵌套 defaultdict
tree = lambda: defaultdict(tree)
config = tree()
config["database"]["host"] = "localhost"
config["database"]["port"] = 5432

24.2 contextlib — 上下文管理器工具集

from contextlib import contextmanager, suppress, redirect_stdout, closing

# contextmanager — 用生成器创建上下文管理器
@contextmanager
def timer(label):
    import time
    start = time.perf_counter()
    try:
        yield
    finally:
        elapsed = time.perf_counter() - start
        print(f"[{label}] {elapsed:.4f}s")

with timer("计算"):
    sum(range(1_000_000))

# suppress — 安全忽略异常
import os
with suppress(FileNotFoundError):
    os.remove("不存在的文件.txt")

# redirect_stdout — 重定向标准输出
from io import StringIO
f = StringIO()
with redirect_stdout(f):
    print("这些内容被重定向了")
output = f.getvalue()

# closing — 确保 close() 被调用
from urllib.request import urlopen
with closing(urlopen("https://example.com")) as page:
    content = page.read()

# ExitStack — 动态管理多个上下文
from contextlib import ExitStack

with ExitStack() as stack:
    files = [stack.enter_context(open(f"file{i}.txt", "w")) for i in range(3)]
    for i, f in enumerate(files):
        f.write(f"file {i}")
# 所有文件在退出时自动关闭

24.3 enum — 枚举类型

from enum import Enum, IntEnum, Flag, auto

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

print(Color.RED)           # Color.RED
print(Color.RED.name)      # "RED"
print(Color.RED.value)     # 1
print(Color(1))            # Color.RED
print(Color["RED"])        # Color.RED
print(list(Color))         # [Color.RED, Color.GREEN, Color.BLUE]

# auto() 自动赋值
class Direction(Enum):
    NORTH = auto()   # 1
    SOUTH = auto()   # 2
    EAST = auto()    # 3
    WEST = auto()    # 4

# IntEnum — 可以和整数比较
class Priority(IntEnum):
    LOW = 1
    MEDIUM = 2
    HIGH = 3

print(Priority.HIGH > Priority.LOW)   # True
print(Priority.HIGH > 2)              # True

# Flag — 可以组合的标志
class Permission(Flag):
    READ = auto()
    WRITE = auto()
    EXECUTE = auto()

perms = Permission.READ | Permission.WRITE
print(Permission.READ in perms)    # True
print(Permission.EXECUTE in perms) # False

# 枚举用于 match-case
def handle_color(color: Color):
    match color:
        case Color.RED:
            return "红色"
        case Color.GREEN:
            return "绿色"
        case Color.BLUE:
            return "蓝色"

24.4 logging — 日志系统

import logging

# 基本配置
logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
)

logger = logging.getLogger(__name__)

# 五个级别
logger.debug("调试信息")
logger.info("一般信息")
logger.warning("警告")
logger.error("错误")
logger.critical("严重错误")

# 带变量的日志(推荐 % 风格,避免不必要的字符串格式化)
user = "Alice"
logger.info("用户 %s 登录", user)

# 记录异常
try:
    1 / 0
except ZeroDivisionError:
    logger.exception("计算出错")  # 自动附加堆栈信息

进阶配置

import logging
from logging.handlers import RotatingFileHandler

# 创建 logger
logger = logging.getLogger("myapp")
logger.setLevel(logging.DEBUG)

# 控制台 handler
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(logging.Formatter("[%(levelname)s] %(message)s"))

# 文件 handler(自动轮转)
file_handler = RotatingFileHandler(
    "app.log", maxBytes=5*1024*1024, backupCount=3
)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(
    logging.Formatter("%(asctime)s [%(levelname)s] %(name)s: %(message)s")
)

logger.addHandler(console)
logger.addHandler(file_handler)

24.5 argparse — 命令行参数解析

import argparse

parser = argparse.ArgumentParser(description="文件处理工具")

# 位置参数
parser.add_argument("input", help="输入文件路径")

# 可选参数
parser.add_argument("-o", "--output", default="output.txt", help="输出文件路径")
parser.add_argument("-n", "--lines", type=int, default=10, help="处理行数")
parser.add_argument("-v", "--verbose", action="store_true", help="详细输出")
parser.add_argument("--format", choices=["json", "csv", "txt"], default="txt")

args = parser.parse_args()

print(f"输入: {args.input}")
print(f"输出: {args.output}")
print(f"行数: {args.lines}")
print(f"详细: {args.verbose}")
python tool.py input.txt -o result.txt -n 100 -v --format json
python tool.py --help

24.6 datetime — 日期与时间处理

from datetime import datetime, date, time, timedelta, timezone

# 当前时间
now = datetime.now()
utc_now = datetime.now(timezone.utc)

# 创建
dt = datetime(2026, 3, 31, 14, 30, 0)
d = date(2026, 3, 31)
t = time(14, 30, 0)

# 格式化
print(now.strftime("%Y-%m-%d %H:%M:%S"))  # 2026-03-31 14:30:00
print(now.isoformat())                      # 2026-03-31T14:30:00.123456

# 解析
dt = datetime.strptime("2026-03-31", "%Y-%m-%d")

# 时间差
delta = timedelta(days=7, hours=3)
next_week = now + delta
diff = datetime(2026, 12, 31) - now
print(f"还有 {diff.days} 天到年底")

# 时区
from zoneinfo import ZoneInfo  # Python 3.9+
shanghai = ZoneInfo("Asia/Shanghai")
tokyo = ZoneInfo("Asia/Tokyo")

shanghai_now = datetime.now(shanghai)
tokyo_now = shanghai_now.astimezone(tokyo)
print(f"上海: {shanghai_now}")
print(f"东京: {tokyo_now}")

24.7 struct — 处理 C 结构体二进制数据

import struct

# 打包: Python 值 → bytes
data = struct.pack(">I2sf", 1, b"Hi", 3.14)  # 大端序: uint32, 2字符, float
print(data)   # b'\x00\x00\x00\x01Hi@H\xf5\xc3'
print(len(data))  # 10

# 解包: bytes → Python 值
values = struct.unpack(">I2sf", data)
print(values)  # (1, b'Hi', 3.140000104904175)

# 常用格式符:
# b/B: int8/uint8    h/H: int16/uint16
# i/I: int32/uint32  q/Q: int64/uint64
# f: float32         d: float64
# s: 字符串(bytes)   ?: bool
# >: 大端  <: 小端  =: 本地  !: 网络字节序

# 读取二进制文件头
def read_bmp_header(filename):
    with open(filename, "rb") as f:
        header = f.read(14)
        magic, size, _, _, offset = struct.unpack("<2sIHHI", header)
        return {
            "magic": magic,
            "file_size": size,
            "data_offset": offset,
        }

24.8 abc — 抽象基类

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self) -> float: ...
    
    @abstractmethod
    def perimeter(self) -> float: ...
    
    def __repr__(self):
        return f"{type(self).__name__}(area={self.area():.2f})"

# 注册虚拟子类
class Circle:
    def __init__(self, r):
        self.r = r
    def area(self):
        return 3.14159 * self.r ** 2
    def perimeter(self):
        return 2 * 3.14159 * self.r

Shape.register(Circle)
print(isinstance(Circle(5), Shape))  # True

24.9 typing — 类型提示扩展

from typing import (
    Any, Union, Optional, Literal, Final, TypeAlias,
    TypeVar, Generic, Protocol, TypedDict, NamedTuple,
    overload, runtime_checkable, get_type_hints,
)

# overload — 函数重载签名
@overload
def process(x: int) -> str: ...
@overload
def process(x: str) -> int: ...

def process(x):
    if isinstance(x, int):
        return str(x)
    return len(x)

# get_type_hints — 运行时获取类型信息
class User:
    name: str
    age: int

print(get_type_hints(User))
# {'name': <class 'str'>, 'age': <class 'int'>}

24.10 dataclasses — 数据类

from dataclasses import dataclass, field, asdict, astuple, fields, replace

@dataclass(frozen=True, slots=True)
class Config:
    host: str = "localhost"
    port: int = 8080
    debug: bool = False
    tags: tuple[str, ...] = ()

config = Config(host="0.0.0.0", tags=("web", "api"))

# 工具函数
print(asdict(config))    # 转为字典
print(astuple(config))   # 转为元组

# replace — 创建修改后的副本
dev_config = replace(config, debug=True, port=3000)

# fields — 获取字段信息
for f in fields(Config):
    print(f"{f.name}: {f.type} = {f.default}")

本章小结:Python 标准库是”自带电池”理念的体现。collections 扩展了内置容器,contextlib 简化了上下文管理,enum 提供了类型安全的枚举,logging 是生产级日志方案,datetime 处理日期时间,struct 桥接二进制数据。善用标准库,减少外部依赖。