全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-19 10 分钟 ✍️ juanwangdev

Python代码重构技术

重构是在不改变代码外部行为的前提下改善其内部结构的技术。

重构原则

何时重构

Python
# 重构时机:
# 1. 添加新功能前(整理现有代码)
# 2. 代码理解困难时(提高可读性)
# 3. 修复Bug后(消除问题根源)
# 4. Code Review时(接受建议)
# 5. 性能优化前(先让代码清晰)

# 重构三定律:
# 1. 小步前进:每次只做一个小改动
# 2. 测试驱动:每次重构后运行测试
# 3. 功能不变:不改变外部行为

提取方法

长方法拆分

Python
# 重构前:长方法难以理解
def process_order(order):
    # 验证订单
    if order.items is None or len(order.items) == 0:
        raise ValueError("Order has no items")
    for item in order.items:
        if item.quantity <= 0:
            raise ValueError("Invalid quantity")
        if item.price <= 0:
            raise ValueError("Invalid price")

    # 计算总价
    total = 0
    for item in order.items:
        total += item.quantity * item.price
    tax = total * 0.1
    final_price = total + tax

    # 应用折扣
    if order.customer.is_premium:
        discount = final_price * 0.1
        final_price -= discount

    # 更新库存
    for item in order.items:
        inventory = get_inventory(item.product_id)
        inventory.quantity -= item.quantity
        save_inventory(inventory)

    # 创建支付记录
    payment = create_payment(order, final_price)

    # 发送通知
    send_email(order.customer.email, "Order confirmed")
    if order.customer.is_premium:
        send_sms(order.customer.phone, "Premium discount applied")

    return payment

# 重构后:职责清晰
def process_order(order):
    validate_order(order)
    final_price = calculate_price(order)
    update_inventory(order)
    payment = create_payment(order, final_price)
    send_notifications(order)
    return payment

def validate_order(order):
    if not order.items:
        raise ValueError("Order has no items")
    for item in order.items:
        validate_item(item)

def validate_item(item):
    if item.quantity <= 0:
        raise ValueError("Invalid quantity")
    if item.price <= 0:
        raise ValueError("Invalid price")

def calculate_price(order):
    total = sum(item.quantity * item.price for item in order.items)
    tax = total * 0.1
    final_price = total + tax
    return apply_discount(final_price, order.customer)

def apply_discount(price, customer):
    if customer.is_premium:
        return price * 0.9
    return price

def update_inventory(order):
    for item in order.items:
        inventory = get_inventory(item.product_id)
        inventory.quantity -= item.quantity
        save_inventory(inventory)

def send_notifications(order):
    send_email(order.customer.email, "Order confirmed")
    if order.customer.is_premium:
        send_sms(order.customer.phone, "Premium discount applied")

提取重复代码

Python
# 重构前:重复代码
def calculate_employee_salary(employee):
    base = employee.base_salary
    bonus = 0
    if employee.performance == 'excellent':
        bonus = base * 0.2
    elif employee.performance == 'good':
        bonus = base * 0.1
    return base + bonus

def calculate_manager_salary(manager):
    base = manager.base_salary
    bonus = 0
    if manager.performance == 'excellent':
        bonus = base * 0.2
    elif manager.performance == 'good':
        bonus = base * 0.1
    team_bonus = manager.team_size * 100
    return base + bonus + team_bonus

# 重构后:提取通用逻辑
def calculate_bonus(base_salary, performance):
    rates = {'excellent': 0.2, 'good': 0.1, 'normal': 0}
    return base_salary * rates.get(performance, 0)

def calculate_employee_salary(employee):
    base = employee.base_salary
    bonus = calculate_bonus(base, employee.performance)
    return base + bonus

def calculate_manager_salary(manager):
    base = manager.base_salary
    bonus = calculate_bonus(base, manager.performance)
    team_bonus = manager.team_size * 100
    return base + bonus + team_bonus

简化条件表达式

分解条件

Python
# 重构前:复杂条件
def get_discount(customer, order):
    if customer.is_premium and order.total > 1000 and customer.order_count > 10:
        return 0.15
    elif customer.is_premium and order.total > 500:
        return 0.1
    elif order.total > 1000:
        return 0.05
    return 0

# 重构后:提取条件方法
def get_discount(customer, order):
    if is_elite_customer(customer, order):
        return 0.15
    if is_premium_large_order(customer, order):
        return 0.1
    if is_large_order(order):
        return 0.05
    return 0

def is_elite_customer(customer, order):
    return customer.is_premium and order.total > 1000 and customer.order_count > 10

def is_premium_large_order(customer, order):
    return customer.is_premium and order.total > 500

def is_large_order(order):
    return order.total > 1000

合并条件

Python
# 重构前:多个条件分支
def should_send_notification(user):
    if user.email_verified:
        if user.notification_enabled:
            if not user.is_suspended:
                return True
    return False

# 重构后:合并条件
def should_send_notification(user):
    return user.email_verified and user.notification_enabled and not user.is_suspended

使用字典替代条件

Python
# 重构前:大量if-elif
def get_status_text(status):
    if status == 'pending':
        return '等待处理'
    elif status == 'processing':
        return '正在处理'
    elif status == 'completed':
        return '已完成'
    elif status == 'failed':
        return '处理失败'
    else:
        return '未知状态'

# 重构后:字典映射
STATUS_TEXT = {
    'pending': '等待处理',
    'processing': '正在处理',
    'completed': '已完成',
    'failed': '处理失败'
}

def get_status_text(status):
    return STATUS_TEXT.get(status, '未知状态')

重构数据结构

提取类

Python
# 重构前:数据与逻辑混杂
class Order:
    def __init__(self, items, customer):
        self.items = items
        self.customer = customer

    def calculate_total(self):
        total = sum(item.price * item.quantity for item in self.items)
        tax = total * self.customer.tax_rate
        discount = total * self.customer.discount_rate
        return total + tax - discount

# 重构后:职责分离
class PriceCalculator:
    def calculate(self, items, customer):
        subtotal = self._calculate_subtotal(items)
        tax = self._calculate_tax(subtotal, customer)
        discount = self._calculate_discount(subtotal, customer)
        return subtotal + tax - discount

    def _calculate_subtotal(self, items):
        return sum(item.price * item.quantity for item in items)

    def _calculate_tax(self, subtotal, customer):
        return subtotal * customer.tax_rate

    def _calculate_discount(self, subtotal, customer):
        return subtotal * customer.discount_rate

class Order:
    def __init__(self, items, customer, calculator=None):
        self.items = items
        self.customer = customer
        self.calculator = calculator or PriceCalculator()

    def calculate_total(self):
        return self.calculator.calculate(self.items, self.customer)

封装字段

Python
# 重构前:直接访问字段
class Customer:
    pass

customer = Customer()
customer.name = 'Alice'
customer.email = 'alice@example.com'

# 重构后:属性封装
class Customer:
    def __init__(self, name, email):
        self._name = name
        self._email = email

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        if not value:
            raise ValueError("Name cannot be empty")
        self._name = value

    @property
    def email(self):
        return self._email

    @email.setter
    def email(self, value):
        if not self._validate_email(value):
            raise ValueError("Invalid email format")
        self._email = value

    def _validate_email(self, email):
        return '@' in email

消除魔法值

替换魔法数

Python
# 重构前:魔法数字
def calculate_shipping(weight):
    if weight <= 1:
        return 5
    elif weight <= 5:
        return 10
    elif weight <= 10:
        return 20
    return weight * 2.5

# 重构后:常量命名
LIGHT_WEIGHT_THRESHOLD = 1
MEDIUM_WEIGHT_THRESHOLD = 5
HEAVY_WEIGHT_THRESHOLD = 10

LIGHT_SHIPPING_FEE = 5
MEDIUM_SHIPPING_FEE = 10
HEAVY_SHIPPING_FEE = 20
HEAVY_RATE = 2.5

def calculate_shipping(weight):
    if weight <= LIGHT_WEIGHT_THRESHOLD:
        return LIGHT_SHIPPING_FEE
    if weight <= MEDIUM_WEIGHT_THRESHOLD:
        return MEDIUM_SHIPPING_FEE
    if weight <= HEAVY_WEIGHT_THRESHOLD:
        return HEAVY_SHIPPING_FEE
    return weight * HEAVY_RATE

移除死代码

删除未使用代码

Python
# 重构前:包含死代码
def process_data(data):
    # 未使用的变量
    unused_config = load_config()

    result = transform(data)

    # 已废弃的逻辑
    if False:  # 永不执行
        legacy_process(data)

    # 注释掉的代码
    # old_result = old_transform(data)

    return result

# 重构后:清理干净
def process_data(data):
    return transform(data)

重构流程

小步重构法

Python
# 1. 确保有测试覆盖
# 2. 选择一个小改动
# 3. 实施改动
# 4. 运行测试
# 5. 提交改动
# 6. 继续下一个改动

# 示例流程:
# Step 1: 提取validate_order方法
# 运行测试 → 成功
# Step 2: 提取calculate_price方法
# 运行测试 → 成功
# Step 3: 提取apply_discount方法
# 运行测试 → 成功
# ...每个步骤都有测试验证

IDE重构工具

Python
# VS Code / PyCharm 重构功能:
# 1. 重命名变量/方法(F2)
# 2. 提取方法
# 3. 提取变量
# 4. 内联变量/方法
# 5. 移动类/方法
# 6. 改变方法签名

# 使用IDE工具可以安全、快速完成重构

重构检查清单

检查项说明
长方法提取为多个小方法
重复代码提取为通用方法
大类分拆为多个职责清晰的类
长参数列表封装为参数对象
魔法值使用命名常量
复杂条件提取条件方法或使用策略模式
死代码删除无用代码

注意:重构前必须有测试覆盖,每次重构后运行测试确保行为不变。

要点总结

  • 提取方法:长方法拆分、重复代码抽取、职责单一化
  • 简化条件:分解复杂条件、合并重复分支、字典替代if-elif
  • 重构数据:提取类分离职责、属性封装验证、命名常量替代魔法值
  • 小步重构:每次只改一小处、测试驱动验证、渐进式改善
  • 使用IDE工具:重命名、提取方法、内联变量等自动化重构
  • 重构时机:添加功能前、理解困难时、修复Bug后、Code Review时

存放路径articles/PYTHON/专家/架构与设计/代码重构技术.md

📝 发现内容有误?点击此处直接编辑

← 上一篇 Python SOLID原则实践
下一篇 → Python依赖注入模式
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库