Python 以简洁优雅著称,但写出真正的 Pythonic 代码需要刻意练习。以下是日常开发中最值得养成的几个习惯。

1. 善用列表推导,但别滥用

列表推导清晰时非常优雅:

# 过滤与转换一步到位
active_users = [u.name for u in users if u.is_active]

# 构建字典
name_map = {u.id: u.name for u in users}

但超过一层嵌套时,可读性会急剧下降。此时用普通循环更清晰:

# 不推荐
result = [x for row in matrix for x in row if x > 0]

# 推荐:拆开写
result = []
for row in matrix:
    for x in row:
        if x > 0:
            result.append(x)

2. 用 | 合并字典(Python 3.9+)

defaults = {"timeout": 30, "retries": 3}
user_config = {"timeout": 60}
final = defaults | user_config
# {'timeout': 60, 'retries': 3}

右边覆盖左边,语义直观。老版本用 {**a, **b} 也可以,但 | 更可读。

3. 用上下文管理器管理资源

不只是文件,任何需要"打开-关闭"的资源都适合:

from contextlib import contextmanager
import time

@contextmanager
def timer(description: str = ""):
    start = time.perf_counter()
    yield
    elapsed = time.perf_counter() - start
    print(f"{description}耗时: {elapsed:.3f}s")

# 使用
with timer("数据处理"):
    process_large_dataset()

4. 使用类型提示

Python 3.5+ 支持类型注解,配合编辑器能大幅减少低级错误:

from typing import Optional

def find_user(user_id: int) -> Optional[dict]:
    """返回用户数据,不存在时返回 None"""
    return users_db.get(user_id)

团队项目中,类型提示的价值尤其明显——它们是可执行的文档。

5. pathlib 替代 os.path

from pathlib import Path

# 旧方式
import os
path = os.path.join("data", "config", "app.json")

# 新方式
path = Path("data") / "config" / "app.json"
content = path.read_text(encoding="utf-8")

Path 对象支持 / 拼接、read_textwrite_text,API 更统一。

6. 用 enumerate 替代 range(len())

# 不 Pythonic
for i in range(len(items)):
    print(f"{i}: {items[i]}")

# Pythonic
for i, item in enumerate(items):
    print(f"{i}: {item}")

7. 用 f-string 格式化

name = "World"
count = 42

# Python 3.6+
print(f"Hello {name}, count is {count}")
print(f"{count:04d}")           # 0042
print(f"{0.1234:.2%}")          # 12.34%

8. 异常处理要具体

# 不好
try:
    value = config["key"]
except:
    value = "default"

# 好
try:
    value = config["key"]
except KeyError:
    value = "default"

捕获过于宽泛的异常会掩盖真正的 bug。永远只捕获你预期会发生的异常类型。


Python 的哲学是"应该有一种——最好只有一种——显而易见的写法"。这些习惯并不复杂,坚持用下去,代码质量会自然提升。