文章

Python 库解析 01

用于记录我在阅览公众号 [数据STUDIO] 时发现的有意思的 Python 库; 用于提升我对 Python 库的认知和积累; 本文章中提到的 Python 有: pathlib, contextlib, _slots_, functools.lru_cache, dataclasses;

Python 库解析 01

本文产生的来源: 数据STUDIO - 告别臃肿代码!Python这6个隐藏功能让效率翻倍

工作期间, 有一个比较容易犯的错误, 就是重复造轮子. 就拿 Python 来说, 有很多优秀的库可快速完成我们想要的某个功能; 但是由于自己的思维定式和认知不够, 导致在写代码时总会出现自己造轮子的情况. 这种情况有很多, 甚至 AI 也会这么做. 一个优秀的程序员应该学会了解自己擅长的编程语言的库, 从通过 AI 查询到自己慢慢积累; 从写笔记教程到看懂库说明(大多是英文的, 但是我的英文奇烂); 这才是一个程序员该有的素质.

接下来将讲解我收集到的库: pathlib, contextlib, _slots_, functools.lru_cache, dataclasses;

1. pathlib

pathlib 是 Python 3 标准库中用于面向对象地处理文件系统路径的模块, 旨在替代传统的 os.path 与大量字符串拼接方式. 在可读性、可维护性以及跨平台一致性方面具有明显优势;

1.1. 设计理念

  • 路径即对象:路径不再是字符串,而是 Path 对象
  • 统一接口:Windows / Linux / macOS 使用同一套 API
  • 链式操作:方法返回新的 Path,避免副作用
  • 与标准库深度集成:可直接传给 open()shutilsubprocess

2. contextlib

contextlib 是 Python 标准库中用于简化和规范上下文管理()with 语句)的核心模块。它的定位非常明确:让资源管理、前后置逻辑、异常收尾代码更简洁、更可读、更不易出错

2.1. 为什么需要 contextlib

在没有上下文管理器时, 资源管理通常是这样的:

1
2
3
4
5
f = open("data.txt")
try:
    data = f.read()
finally:
    f.close()

问题在于:

  • 模板代码冗长
  • 容易遗漏 close() / release()
  • 多资源嵌套时可读性急剧下降

with 语句 + 上下文管理器的目标是:

把“进入 + 清理”逻辑绑定成一个原子结构

contextlib 的作用是: 降低你编写自定义上下文管理器的成本

3. __slots__

在 Python 中,__slots__ 是一个类级别的特殊属性,用于显式声明实例允许拥有的属性集合。它主要用于内存优化属性访问约束,在对性能和对象结构有明确要求的代码中非常常见;

3.1. __slots__ 的基本作用

3.1.1. 限制实例属性

默认情况下,Python 实例通过 __dict__ 动态存储属性:

1
2
3
4
5
6
class A:
    pass

a = A()
a.x = 1
a.y = 2

使用 __slots__ 后,只能定义声明过的属性

1
2
3
4
5
6
7
class B:
    __slots__ = ('x', 'y')

b = B()
b.x = 1
b.y = 2
b.z = 3      # AttributeError

3.1.2. 减少内存占用

  • 不再为每个实例分配 __dict__
  • 属性存储为更紧凑的结构(类似 C struct)
1
2
3
4
5
class Normal:
    pass

class Slotted:
    __slots__ = ('x', 'y')

在大量小对象(如状态对象、数据载体、节点)场景中,内存差异非常明显。

4. functools.lru_cache

functools.lru_cache 是 Python 标准库中用于函数级结果缓存(memoization)*的装饰器,核心目标是在*函数参数相同的情况下避免重复计算,从而显著提升性能

4.1. 基本定义

1
functools.lru_cache(maxsize=128, typed=False)
  • LRU:Least Recently Used(最近最少使用)
  • 缓存单位:函数调用结果
  • 缓存键:由函数参数构成(必须可 hash)

4.2. 最基本用法

1
2
3
4
5
6
7
from functools import lru_cache

@lru_cache(maxsize=128)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

行为说明

  • 相同 n 的调用只计算一次
  • 超过 maxsize 后,最久未使用的结果会被淘汰

5. dataclasses

dataclasses 是 Python 3.7 引入的标准库,用于快速定义以数据为中心的类(data-centric class),显著减少样板代码,并提升可读性与可维护性。在工程实践中,它常被视为“轻量级、类型友好的 POJO / DTO 实现方案”。


5.1. 核心价值

在不使用 dataclasses 的情况下,一个典型数据类通常需要手写:

  • __init__
  • __repr__
  • __eq__
  • 可选的 __hash__

@dataclass 可以自动生成上述方法,并与 类型注解 深度结合。


5.3. 最基本用法

1
2
3
4
5
6
from dataclasses import dataclass

@dataclass
class Point:
    x: float
    y: float

等价于(逻辑上):

1
2
3
4
5
6
7
8
9
10
class Point:
    def __init__(self, x: float, y: float):
        self.x = x
        self.y = y

    def __repr__(self):
        return "Point(x=..., y=...)"

    def __eq__(self, other):
        ...

使用示例:

1
2
3
4
5
p1 = Point(1.0, 2.0)
p2 = Point(1.0, 2.0)

p1 == p2      # True
print(p1)    # Point(x=1.0, y=2.0)
本文由作者按照 CC BY 4.0 进行授权