大家好,我是正在实战各种 AI 项目的程序员晚枫。
认识我的朋友都知道,我写 Python 不算晚。2018年就开始了,至今也有8年。但我认真告诉你:直到我仔仔细细读完《流畅的Python(第2版)》,我才意识到,自己之前写的很多代码,其实都是错的——或者说,是"不 Pythonic 的"。
这不是在故意谦虚,我举几个真实的例子。
坏习惯 1:用 len() 判断容器是否为空
我以前写了无数次这样的代码:
if len(my_list) > 0: do_something()
直到书里告诉我,Python 的对象有 __bool__ 和 __len__ 协议。所有内置容器,空时都会被当作 False。
正确写法:
if my_list: do_something()
更简洁,更 Pythonic,运行还更快。这是一个入门级错误,但我写了不知道多少年。
坏习惯 2:用类属性当默认参数
这是个经典陷阱,不是所有人都踩过,但踩过的人都印象深刻:
# 这段代码有严重 bugclassConfig:def__init__(self, options={}):# ← 危险! self.options = options
所有实例会共享同一个字典对象,改了一个,其他全部跟着变。
后果:线上偶发性数据污染,极难复现,是噩梦级的调试场景。
我知道这个道理,但我还是在实际项目里犯过。因为我从没系统理解过 Python 的对象引用机制——变量不是"盒子",而是"便利贴",贴在对象上的标签。书里用一整章(第9讲)把这个讲透了。
坏习惯 3:不会用装饰器,只会复制粘贴
装饰器用了很多年,但我写过最复杂的装饰器,也就是带一个参数的那种。
直到我读到书里讲装饰器的那章,才知道:
functools.wraps 为什么必须加——不加的话,被装饰函数的 __name__ 和 __doc__ 会丢失,框架层面可能因此找不到正确的函数元信息
这些东西,网上的教程其实都有,但分散、零碎、语焉不详。这本书是我见过讲得最系统的。
坏习惯 4:觉得生成器和迭代器"差不多"
以前我以为 yield 就是"返回一个值",和 return 没本质区别。
这是错的。
# 错误认知:生成器和普通函数差不多defmy_generator(n):for i in range(n):return i # ← 生成器里 return 等价于 raise StopIteration
正确理解:yield 挂起函数执行,保留局部状态;return 终止函数。每次调用 next(),函数从上次 yield 的位置继续执行。
这个区别的实际后果:生成器占用常量级内存,适合处理大数据流。而列表推导式会把所有数据一次性加载进内存,大数据场景下直接 OOM。
更重要的是:生成器是理解 yield from 和协程的基础。yield from 可以把一个生成器的任务委托给子生成器,而协程(async def)本质上是使用 yield 语法的生成器的进化版——这些概念不连起来理解,asyncio 就永远是黑盒。
我的改变
读完《流畅的Python(第2版)》之后,我的代码有什么变化?
- 重复写的工具函数少了,因为很多 Python 内置就支持
- 同事 code review 的时候,提的问题少了一半
更重要的是:我对 Python 的理解,从"使用者"升级到了"理解者"。
我开设了直播共读课
《流畅的Python(第2版)》是好书,但真的不容易独自啃下来。800 多页,全是干货,很多人买了之后,翻了前三章,就搁置了。
我自己也是读了好几遍,感觉还没有真正吸收,有些问题很想找人讨论一下。
所以我决定开设一门直播共读课:
- 每周一场直播,逐章精讲,专门挑"容易写错、容易忽视"的知识点重点讲
价格:原价 499 元,试运营期间 299 元,并且我还会包邮送这套书(含上下册)。
这个价格不求盈利,我也想通过这套课程,给自己一个沉淀的机会。想找一群真心想学的人,一起把这本书读透。
报名方式
添加我的微信 python-office,备注「流畅」,我来拉你进群。
你以为自己离"真正掌握 Python"很远,其实差的只是找到一本对的书,和一群陪你读下去的人。期待在群里见到你。