第 12 章 · 常见陷阱与反 Java 习惯¶
本章是"反 Java 习惯"清单——把前面各章散落的陷阱汇总,并补充新条目。每条给 ❌ 反例 和 ✅ 正解。建议把它当备忘录,写完代码回来过一遍。
12.1 比较与真值¶
用 == 判 None¶
if x == True:¶
字符串/列表用 == 比内容(Java 直觉相反)¶
# Java: a == b 比引用,是著名 bug
# Python: a == b 比值,正是你想要的 ✅
assert "abc" == "abc"
assert [1, 2] == [1, 2]
浮点直接比相等¶
12.2 可变性与拷贝¶
可变默认参数(第 2 章)¶
b = a 当拷贝用(第 3 章)¶
tuple 装可变对象¶
大量字符串 + 拼接¶
12.3 语法与习惯¶
for i in range(len(x)) 取索引¶
for i in range(len(xs)): print(xs[i]) # ❌ Java 习惯
for x in xs: print(x) # ✅ 直接遍历
for i, x in enumerate(xs): print(i, x) # ✅ 要索引用 enumerate
不用 with 打开文件¶
f = open(path); data = f.read(); f.close() # ❌ 异常时忘记关闭
with open(path) as f: data = f.read() # ✅ 自动关闭
camelCase 命名¶
手写 switch 链 / 手动索引取值¶
# ❌ if/elif 长链做值映射
if op == "add": ...
elif op == "sub": ...
# ✅ 字典分发 或 match(第 1 章)
actions = {"add": do_add, "sub": do_sub}
actions[op]()
12.4 函数与作用域¶
lambda 晚绑定(第 2 章)¶
funcs = [lambda: i for i in range(3)]
[f() for f in funcs] # ❌ [2, 2, 2]
funcs = [lambda i=i: i for i in range(3)] # ✅ 默认参数固化
滥用 lambda 写复杂逻辑¶
key = lambda u: (u["dept"], -u["salary"], u["name"].lower()) # ❌ 太长难读
def sort_key(u): return (u["dept"], -u["salary"], u["name"].lower()) # ✅ 命名函数
忽略返回值(函数默认返回 None)¶
裸 except 吞一切(第 5 章)¶
try 块过大¶
try: # ❌ 把一大段成功代码塞进 try,误捕
val = parse(x); result = process(val); save(result)
except Exception: ...
# ✅ 只包可能出错的那行,成功路径放 else
12.5 模块与工程化¶
文件名遮蔽标准库(第 6 章)¶
全局装包(第 10 章)¶
from x import *¶
groupby 没排序(第 9 章)¶
12.6 并发¶
CPU 密集用多线程(第 11 章)¶
threads = [Thread(target=heavy_cpu) for _ in range(4)] # ❌ GIL,不并行
with Pool(4) as p: p.map(heavy_cpu, items) # ✅ 多进程真并行
在循环里建大量进程/线程而不限流¶
for url in urls: Thread(target=fetch, args=(url,)).start() # ❌ 线程爆炸
with ThreadPoolExecutor(max_workers=10) as ex: ... # ✅ 限流
12.7 自检清单¶
写完一段 Python 代码,回来问自己:
- 有没有用
== None?换成is None - 有没有
for i in range(len(...))?换成直接遍历 /enumerate - 可变默认参数有没有用
None哨兵? - 拼字符串有没有用
join? - 文件/资源有没有用
with? -
try块是不是太大了?except是不是裸的? - 命名是不是
snake_case? - CPU 密集任务有没有误用多线程?
心态转换
每条陷阱背后都是同一条原则:别用 Java 的肌肉记忆,用 Python 的方式。当你发现自己在"翻译 Java",停下来查一下有没有更 Pythonic 的写法——通常有。
上一章:第 11 章 · 并发模型 | 下一章:第 13 章 · 贯穿项目实战。