python-anti-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePython Anti-Patterns Checklist
Python反模式检查清单
A reference checklist of common mistakes and anti-patterns in Python code. Review this before finalizing implementations to catch issues early.
一份关于Python代码中常见错误和反模式的参考检查清单。在完成实现前查阅此清单,以便及早发现问题。
When to Use This Skill
何时使用本指南
- Reviewing code before merge
- Debugging mysterious issues
- Teaching or learning Python best practices
- Establishing team coding standards
- Refactoring legacy code
Note: This skill focuses on what to avoid. For guidance on positive patterns and architecture, see the skill.
python-design-patterns- 代码合并前的评审
- 调试疑难问题
- 教授或学习Python最佳实践
- 建立团队编码标准
- 重构遗留代码
注意: 本指南重点介绍需要避免的内容。如需了解积极模式和架构的指导,请查看相关内容。
python-design-patternsInfrastructure Anti-Patterns
基础设施反模式
Scattered Timeout/Retry Logic
分散的超时/重试逻辑
python
undefinedpython
undefinedBAD: Timeout logic duplicated everywhere
BAD: Timeout logic duplicated everywhere
def fetch_user(user_id):
try:
return requests.get(url, timeout=30)
except Timeout:
logger.warning("Timeout fetching user")
return None
def fetch_orders(user_id):
try:
return requests.get(url, timeout=30)
except Timeout:
logger.warning("Timeout fetching orders")
return None
**Fix:** Centralize in decorators or client wrappers.
```pythondef fetch_user(user_id):
try:
return requests.get(url, timeout=30)
except Timeout:
logger.warning("Timeout fetching user")
return None
def fetch_orders(user_id):
try:
return requests.get(url, timeout=30)
except Timeout:
logger.warning("Timeout fetching orders")
return None
**修复方案:** 使用装饰器或客户端包装器集中处理。
```pythonGOOD: Centralized retry logic
GOOD: Centralized retry logic
@retry(stop=stop_after_attempt(3), wait=wait_exponential())
def http_get(url: str) -> Response:
return requests.get(url, timeout=30)
undefined@retry(stop=stop_after_attempt(3), wait=wait_exponential())
def http_get(url: str) -> Response:
return requests.get(url, timeout=30)
undefinedDouble Retry
重复重试
python
undefinedpython
undefinedBAD: Retrying at multiple layers
BAD: Retrying at multiple layers
@retry(max_attempts=3) # Application retry
def call_service():
return client.request() # Client also has retry configured!
**Fix:** Retry at one layer only. Know your infrastructure's retry behavior.@retry(max_attempts=3) # Application retry
def call_service():
return client.request() # Client also has retry configured!
**修复方案:** 仅在一个层级进行重试。了解你的基础设施的重试行为。Hard-Coded Configuration
硬编码配置
python
undefinedpython
undefinedBAD: Secrets and config in code
BAD: Secrets and config in code
DB_HOST = "prod-db.example.com"
API_KEY = "sk-12345"
def connect():
return psycopg.connect(f"host={DB_HOST}...")
**Fix:** Use environment variables with typed settings.
```pythonDB_HOST = "prod-db.example.com"
API_KEY = "sk-12345"
def connect():
return psycopg.connect(f"host={DB_HOST}...")
**修复方案:** 使用带类型的环境变量配置。
```pythonGOOD
GOOD
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
db_host: str = Field(alias="DB_HOST")
api_key: str = Field(alias="API_KEY")
settings = Settings()
undefinedfrom pydantic_settings import BaseSettings
class Settings(BaseSettings):
db_host: str = Field(alias="DB_HOST")
api_key: str = Field(alias="API_KEY")
settings = Settings()
undefinedArchitecture Anti-Patterns
架构反模式
Exposed Internal Types
暴露内部类型
python
undefinedpython
undefinedBAD: Leaking ORM model to API
BAD: Leaking ORM model to API
@app.get("/users/{id}")
def get_user(id: str) -> UserModel: # SQLAlchemy model
return db.query(UserModel).get(id)
**Fix:** Use DTOs/response models.
```python@app.get("/users/{id}")
def get_user(id: str) -> UserModel: # SQLAlchemy model
return db.query(UserModel).get(id)
**修复方案:** 使用DTO/响应模型。
```pythonGOOD
GOOD
@app.get("/users/{id}")
def get_user(id: str) -> UserResponse:
user = db.query(UserModel).get(id)
return UserResponse.from_orm(user)
undefined@app.get("/users/{id}")
def get_user(id: str) -> UserResponse:
user = db.query(UserModel).get(id)
return UserResponse.from_orm(user)
undefinedMixed I/O and Business Logic
I/O与业务逻辑混合
python
undefinedpython
undefinedBAD: SQL embedded in business logic
BAD: SQL embedded in business logic
def calculate_discount(user_id: str) -> float:
user = db.query("SELECT * FROM users WHERE id = ?", user_id)
orders = db.query("SELECT * FROM orders WHERE user_id = ?", user_id)
# Business logic mixed with data access
if len(orders) > 10:
return 0.15
return 0.0
**Fix:** Repository pattern. Keep business logic pure.
```pythondef calculate_discount(user_id: str) -> float:
user = db.query("SELECT * FROM users WHERE id = ?", user_id)
orders = db.query("SELECT * FROM orders WHERE user_id = ?", user_id)
# Business logic mixed with data access
if len(orders) > 10:
return 0.15
return 0.0
**修复方案:** 使用仓储模式,保持业务逻辑纯净。
```pythonGOOD
GOOD
def calculate_discount(user: User, orders: list[Order]) -> float:
# Pure business logic, easily testable
if len(orders) > 10:
return 0.15
return 0.0
undefineddef calculate_discount(user: User, orders: list[Order]) -> float:
# Pure business logic, easily testable
if len(orders) > 10:
return 0.15
return 0.0
undefinedError Handling Anti-Patterns
错误处理反模式
Bare Exception Handling
裸异常捕获
python
undefinedpython
undefinedBAD: Swallowing all exceptions
BAD: Swallowing all exceptions
try:
process()
except Exception:
pass # Silent failure - bugs hidden forever
**Fix:** Catch specific exceptions. Log or handle appropriately.
```pythontry:
process()
except Exception:
pass # Silent failure - bugs hidden forever
**修复方案:** 捕获特定异常。适当记录或处理。
```pythonGOOD
GOOD
try:
process()
except ConnectionError as e:
logger.warning("Connection failed, will retry", error=str(e))
raise
except ValueError as e:
logger.error("Invalid input", error=str(e))
raise BadRequestError(str(e))
undefinedtry:
process()
except ConnectionError as e:
logger.warning("Connection failed, will retry", error=str(e))
raise
except ValueError as e:
logger.error("Invalid input", error=str(e))
raise BadRequestError(str(e))
undefinedIgnored Partial Failures
忽略部分失败
python
undefinedpython
undefinedBAD: Stops on first error
BAD: Stops on first error
def process_batch(items):
results = []
for item in items:
result = process(item) # Raises on error - batch aborted
results.append(result)
return results
**Fix:** Capture both successes and failures.
```pythondef process_batch(items):
results = []
for item in items:
result = process(item) # Raises on error - batch aborted
results.append(result)
return results
**修复方案:** 同时记录成功和失败的结果。
```pythonGOOD
GOOD
def process_batch(items) -> BatchResult:
succeeded = {}
failed = {}
for idx, item in enumerate(items):
try:
succeeded[idx] = process(item)
except Exception as e:
failed[idx] = e
return BatchResult(succeeded, failed)
undefineddef process_batch(items) -> BatchResult:
succeeded = {}
failed = {}
for idx, item in enumerate(items):
try:
succeeded[idx] = process(item)
except Exception as e:
failed[idx] = e
return BatchResult(succeeded, failed)
undefinedMissing Input Validation
缺少输入验证
python
undefinedpython
undefinedBAD: No validation
BAD: No validation
def create_user(data: dict):
return User(**data) # Crashes deep in code on bad input
**Fix:** Validate early at API boundaries.
```pythondef create_user(data: dict):
return User(**data) # Crashes deep in code on bad input
**修复方案:** 在API边界处尽早进行验证。
```pythonGOOD
GOOD
def create_user(data: dict) -> User:
validated = CreateUserInput.model_validate(data)
return User.from_input(validated)
undefineddef create_user(data: dict) -> User:
validated = CreateUserInput.model_validate(data)
return User.from_input(validated)
undefinedResource Anti-Patterns
资源反模式
Unclosed Resources
未关闭的资源
python
undefinedpython
undefinedBAD: File never closed
BAD: File never closed
def read_file(path):
f = open(path)
return f.read() # What if this raises?
**Fix:** Use context managers.
```pythondef read_file(path):
f = open(path)
return f.read() # What if this raises?
**修复方案:** 使用上下文管理器。
```pythonGOOD
GOOD
def read_file(path):
with open(path) as f:
return f.read()
undefineddef read_file(path):
with open(path) as f:
return f.read()
undefinedBlocking in Async
异步代码中的阻塞操作
python
undefinedpython
undefinedBAD: Blocks the entire event loop
BAD: Blocks the entire event loop
async def fetch_data():
time.sleep(1) # Blocks everything!
response = requests.get(url) # Also blocks!
**Fix:** Use async-native libraries.
```pythonasync def fetch_data():
time.sleep(1) # Blocks everything!
response = requests.get(url) # Also blocks!
**修复方案:** 使用原生异步库。
```pythonGOOD
GOOD
async def fetch_data():
await asyncio.sleep(1)
async with httpx.AsyncClient() as client:
response = await client.get(url)
undefinedasync def fetch_data():
await asyncio.sleep(1)
async with httpx.AsyncClient() as client:
response = await client.get(url)
undefinedType Safety Anti-Patterns
类型安全反模式
Missing Type Hints
缺少类型提示
python
undefinedpython
undefinedBAD: No types
BAD: No types
def process(data):
return data["value"] * 2
**Fix:** Annotate all public functions.
```pythondef process(data):
return data["value"] * 2
**修复方案:** 为所有公共函数添加类型注解。
```pythonGOOD
GOOD
def process(data: dict[str, int]) -> int:
return data["value"] * 2
undefineddef process(data: dict[str, int]) -> int:
return data["value"] * 2
undefinedUntyped Collections
无类型的集合
python
undefinedpython
undefinedBAD: Generic list without type parameter
BAD: Generic list without type parameter
def get_users() -> list:
...
**Fix:** Use type parameters.
```pythondef get_users() -> list:
...
**修复方案:** 使用类型参数。
```pythonGOOD
GOOD
def get_users() -> list[User]:
...
undefineddef get_users() -> list[User]:
...
undefinedTesting Anti-Patterns
测试反模式
Only Testing Happy Paths
仅测试正常路径
python
undefinedpython
undefinedBAD: Only tests success case
BAD: Only tests success case
def test_create_user():
user = service.create_user(valid_data)
assert user.id is not None
**Fix:** Test error conditions and edge cases.
```pythondef test_create_user():
user = service.create_user(valid_data)
assert user.id is not None
**修复方案:** 测试错误场景和边缘情况。
```pythonGOOD
GOOD
def test_create_user_success():
user = service.create_user(valid_data)
assert user.id is not None
def test_create_user_invalid_email():
with pytest.raises(ValueError, match="Invalid email"):
service.create_user(invalid_email_data)
def test_create_user_duplicate_email():
service.create_user(valid_data)
with pytest.raises(ConflictError):
service.create_user(valid_data)
undefineddef test_create_user_success():
user = service.create_user(valid_data)
assert user.id is not None
def test_create_user_invalid_email():
with pytest.raises(ValueError, match="Invalid email"):
service.create_user(invalid_email_data)
def test_create_user_duplicate_email():
service.create_user(valid_data)
with pytest.raises(ConflictError):
service.create_user(valid_data)
undefinedOver-Mocking
过度Mock
python
undefinedpython
undefinedBAD: Mocking everything
BAD: Mocking everything
def test_user_service():
mock_repo = Mock()
mock_cache = Mock()
mock_logger = Mock()
mock_metrics = Mock()
# Test doesn't verify real behavior
**Fix:** Use integration tests for critical paths. Mock only external services.def test_user_service():
mock_repo = Mock()
mock_cache = Mock()
mock_logger = Mock()
mock_metrics = Mock()
# Test doesn't verify real behavior
**修复方案:** 对关键路径使用集成测试。仅Mock外部服务。Quick Review Checklist
快速评审检查清单
Before finalizing code, verify:
- No scattered timeout/retry logic (centralized)
- No double retry (app + infrastructure)
- No hard-coded configuration or secrets
- No exposed internal types (ORM models, protobufs)
- No mixed I/O and business logic
- No bare
except Exception: pass - No ignored partial failures in batches
- No missing input validation
- No unclosed resources (using context managers)
- No blocking calls in async code
- All public functions have type hints
- Collections have type parameters
- Error paths are tested
- Edge cases are covered
在完成代码前,验证以下内容:
- 不存在分散的超时/重试逻辑(已集中处理)
- 不存在重复重试(应用层+基础设施层)
- 不存在硬编码的配置或密钥
- 不存在暴露的内部类型(ORM模型、protobufs)
- 不存在I/O与业务逻辑混合的情况
- 不存在这种裸异常捕获
except Exception: pass - 不存在批量处理中忽略部分失败的情况
- 不存在缺少输入验证的情况
- 不存在未关闭的资源(已使用上下文管理器)
- 不存在异步代码中的阻塞调用
- 所有公共函数都有类型提示
- 集合都带有类型参数
- 错误路径已测试
- 边缘情况已覆盖
Common Fixes Summary
常见修复方案汇总
| Anti-Pattern | Fix |
|---|---|
| Scattered retry logic | Centralized decorators |
| Hard-coded config | Environment variables + pydantic-settings |
| Exposed ORM models | DTO/response schemas |
| Mixed I/O + logic | Repository pattern |
| Bare except | Catch specific exceptions |
| Batch stops on error | Return BatchResult with successes/failures |
| No validation | Validate at boundaries with Pydantic |
| Unclosed resources | Context managers |
| Blocking in async | Async-native libraries |
| Missing types | Type annotations on all public APIs |
| Only happy path tests | Test errors and edge cases |
| 反模式 | 修复方案 |
|---|---|
| 分散的重试逻辑 | 使用集中式装饰器 |
| 硬编码配置 | 环境变量 + pydantic-settings |
| 暴露ORM模型 | 使用DTO/响应模型 |
| I/O与逻辑混合 | 仓储模式 |
| 裸异常捕获 | 捕获特定异常 |
| 批量处理遇错即停 | 返回包含成功/失败结果的BatchResult |
| 无输入验证 | 在边界处使用Pydantic验证 |
| 未关闭资源 | 上下文管理器 |
| 异步代码中的阻塞操作 | 原生异步库 |
| 缺少类型提示 | 为所有公共API添加类型注解 |
| 仅测试正常路径 | 测试错误和边缘情况 |