Python 概览

自动关联目录:Python 概览

设计取舍

取舍换来什么代价
动态类型 + 解释执行写得快、改得快运行慢,重构靠工具
一切皆对象语义统一、反射方便内存开销大(一个 int 约 28 字节)
GIL实现简单、单线程快、C 扩展易写多线程无法利用多核
强制缩进格式天然统一复制粘贴容易出错
庞大标准库开箱即用标准库风格不统一(历史包袱)

内建容器怎么选

容器是否有序是否可变典型用途复杂度
list是是通用序列、栈尾部增删O(1)O(1),头部O(n)O(n)
tuple是否固定结构、字典键——
dict是(插入序)是映射、计数平均O(1)O(1)
set否是去重、成员判断平均O(1)O(1)
deque是是队列(两端操作)两端O(1)O(1)
heapq部分是优先级队列推/弹O(log⁡n)O(\log n)

循环里判断成员用 set 而不是 list——这是最常见的"改一个词快十倍"。

迭代器与生成器

生成器(yield)是 Python 里最实用的抽象之一:

好处说明
惰性不一次性构造全部数据,省内存
可组合管道式处理,读起来像流水线
支持无限序列理论上可以一直产出
def read_lines(path):
    with open(path) as f:
        for line in f:
            yield line.rstrip("\n")

注意生成器只能遍历一次,需要复用就转成 list。

GIL 到底限制了什么

GIL(全局解释器锁)保证同一时刻只有一个线程执行 Python 字节码。

场景多线程是否有效
CPU 密集(纯 Python 计算)无效,甚至因为切换更慢
IO 密集(网络、磁盘)有效,IO 时会释放 GIL
NumPy / C 扩展的大块计算有效——扩展里可以主动释放 GIL

所以:CPU 密集用 multiprocessing,IO 密集用 asyncio 或线程池。

常见性能陷阱

陷阱改法
循环里 str +=''.join(list)(CPython 有优化,但别依赖)
循环里 list 成员判断转 set
逐元素数值计算NumPy 向量化
频繁 dict[key] + try/exceptdict.get 或 collections.defaultdict
大量小对象__slots__、或用 array/NumPy
反复 len() 在条件里通常无所谓,但热循环里先取出来

语言特性速查

特性用途
列表/字典推导式简洁构造,别嵌套超过两层
装饰器无侵入地加行为(计时、缓存、注册)
上下文管理器 with资源自动释放
*args / **kwargs可变参数与转发
切片a[::2]、a[::-1]
解包a, *rest = xs、{**d1, **d2}
functools.lru_cache一行加记忆化
类型注解配合 mypy,规模化的前提

与 C++ 的思维差异

从 C++ 过来要注意说明
没有真正的私有_name 只是约定
循环变量泄漏for 结束后变量仍在作用域
is 与 ==is 比身份,== 比值;小整数有缓存陷阱
深浅拷贝copy.copy vs copy.deepcopy
没有 switch3.10 起有 match