python-anti-patterns

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Python 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
python-design-patterns
skill.
  • 代码合并前的评审
  • 调试疑难问题
  • 教授或学习Python最佳实践
  • 建立团队编码标准
  • 重构遗留代码
注意: 本指南重点介绍需要避免的内容。如需了解积极模式和架构的指导,请查看
python-design-patterns
相关内容。

Infrastructure Anti-Patterns

基础设施反模式

Scattered Timeout/Retry Logic

分散的超时/重试逻辑

python
undefined
python
undefined

BAD: 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.

```python
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

**修复方案:** 使用装饰器或客户端包装器集中处理。

```python

GOOD: 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)
undefined

Double Retry

重复重试

python
undefined
python
undefined

BAD: 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
undefined
python
undefined

BAD: 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.

```python
DB_HOST = "prod-db.example.com" API_KEY = "sk-12345"
def connect(): return psycopg.connect(f"host={DB_HOST}...")

**修复方案:** 使用带类型的环境变量配置。

```python

GOOD

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()
undefined
from pydantic_settings import BaseSettings
class Settings(BaseSettings): db_host: str = Field(alias="DB_HOST") api_key: str = Field(alias="API_KEY")
settings = Settings()
undefined

Architecture Anti-Patterns

架构反模式

Exposed Internal Types

暴露内部类型

python
undefined
python
undefined

BAD: 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/响应模型。

```python

GOOD

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)
undefined

Mixed I/O and Business Logic

I/O与业务逻辑混合

python
undefined
python
undefined

BAD: 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.

```python
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

**修复方案:** 使用仓储模式,保持业务逻辑纯净。

```python

GOOD

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
undefined
def calculate_discount(user: User, orders: list[Order]) -> float: # Pure business logic, easily testable if len(orders) > 10: return 0.15 return 0.0
undefined

Error Handling Anti-Patterns

错误处理反模式

Bare Exception Handling

裸异常捕获

python
undefined
python
undefined

BAD: 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.

```python
try: process() except Exception: pass # Silent failure - bugs hidden forever

**修复方案:** 捕获特定异常。适当记录或处理。

```python

GOOD

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))
undefined
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))
undefined

Ignored Partial Failures

忽略部分失败

python
undefined
python
undefined

BAD: 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.

```python
def process_batch(items): results = [] for item in items: result = process(item) # Raises on error - batch aborted results.append(result) return results

**修复方案:** 同时记录成功和失败的结果。

```python

GOOD

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)
undefined
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)
undefined

Missing Input Validation

缺少输入验证

python
undefined
python
undefined

BAD: 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.

```python
def create_user(data: dict): return User(**data) # Crashes deep in code on bad input

**修复方案:** 在API边界处尽早进行验证。

```python

GOOD

GOOD

def create_user(data: dict) -> User: validated = CreateUserInput.model_validate(data) return User.from_input(validated)
undefined
def create_user(data: dict) -> User: validated = CreateUserInput.model_validate(data) return User.from_input(validated)
undefined

Resource Anti-Patterns

资源反模式

Unclosed Resources

未关闭的资源

python
undefined
python
undefined

BAD: 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.

```python
def read_file(path): f = open(path) return f.read() # What if this raises?

**修复方案:** 使用上下文管理器。

```python

GOOD

GOOD

def read_file(path): with open(path) as f: return f.read()
undefined
def read_file(path): with open(path) as f: return f.read()
undefined

Blocking in Async

异步代码中的阻塞操作

python
undefined
python
undefined

BAD: 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.

```python
async def fetch_data(): time.sleep(1) # Blocks everything! response = requests.get(url) # Also blocks!

**修复方案:** 使用原生异步库。

```python

GOOD

GOOD

async def fetch_data(): await asyncio.sleep(1) async with httpx.AsyncClient() as client: response = await client.get(url)
undefined
async def fetch_data(): await asyncio.sleep(1) async with httpx.AsyncClient() as client: response = await client.get(url)
undefined

Type Safety Anti-Patterns

类型安全反模式

Missing Type Hints

缺少类型提示

python
undefined
python
undefined

BAD: No types

BAD: No types

def process(data): return data["value"] * 2

**Fix:** Annotate all public functions.

```python
def process(data): return data["value"] * 2

**修复方案:** 为所有公共函数添加类型注解。

```python

GOOD

GOOD

def process(data: dict[str, int]) -> int: return data["value"] * 2
undefined
def process(data: dict[str, int]) -> int: return data["value"] * 2
undefined

Untyped Collections

无类型的集合

python
undefined
python
undefined

BAD: Generic list without type parameter

BAD: Generic list without type parameter

def get_users() -> list: ...

**Fix:** Use type parameters.

```python
def get_users() -> list: ...

**修复方案:** 使用类型参数。

```python

GOOD

GOOD

def get_users() -> list[User]: ...
undefined
def get_users() -> list[User]: ...
undefined

Testing Anti-Patterns

测试反模式

Only Testing Happy Paths

仅测试正常路径

python
undefined
python
undefined

BAD: 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.

```python
def test_create_user(): user = service.create_user(valid_data) assert user.id is not None

**修复方案:** 测试错误场景和边缘情况。

```python

GOOD

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)
undefined
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)
undefined

Over-Mocking

过度Mock

python
undefined
python
undefined

BAD: 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-PatternFix
Scattered retry logicCentralized decorators
Hard-coded configEnvironment variables + pydantic-settings
Exposed ORM modelsDTO/response schemas
Mixed I/O + logicRepository pattern
Bare exceptCatch specific exceptions
Batch stops on errorReturn BatchResult with successes/failures
No validationValidate at boundaries with Pydantic
Unclosed resourcesContext managers
Blocking in asyncAsync-native libraries
Missing typesType annotations on all public APIs
Only happy path testsTest errors and edge cases
反模式修复方案
分散的重试逻辑使用集中式装饰器
硬编码配置环境变量 + pydantic-settings
暴露ORM模型使用DTO/响应模型
I/O与逻辑混合仓储模式
裸异常捕获捕获特定异常
批量处理遇错即停返回包含成功/失败结果的BatchResult
无输入验证在边界处使用Pydantic验证
未关闭资源上下文管理器
异步代码中的阻塞操作原生异步库
缺少类型提示为所有公共API添加类型注解
仅测试正常路径测试错误和边缘情况