
Python代码重构技巧一、什么是重构重构是在不改变代码外部行为的前提下改善代码内部结构的过程。1.1 重构的目标- 提高代码可读性- 降低代码复杂度- 提高可维护性- 消除代码异味- 为新功能做准备1.2 重构的原则- 小步前进- 频繁测试- 保持功能不变- 一次只做一件事二、提取函数将复杂的代码块提取为独立的函数。# 重构前def process_order(order):# 计算总价total 0for item in order[items]:total item[price] * item[quantity]# 应用折扣if order[customer_type] vip:total * 0.9# 计算税费tax total * 0.1total taxreturn total# 重构后def calculate_subtotal(items):return sum(item[price] * item[quantity] for item in items)def apply_discount(total, customer_type):if customer_type vip:return total * 0.9return totaldef calculate_tax(total):return total * 0.1def process_order(order):subtotal calculate_subtotal(order[items])discounted apply_discount(subtotal, order[customer_type])tax calculate_tax(discounted)return discounted tax三、简化条件表达式3.1 提取条件到函数# 重构前if user.age 18 and user.has_license and not user.is_suspended:allow_driving()# 重构后def can_drive(user):return user.age 18 and user.has_license and not user.is_suspendedif can_drive(user):allow_driving()3.2 使用卫语句# 重构前def calculate_discount(customer):if customer is not None:if customer.is_active:if customer.total_purchases 1000:return 0.1else:return 0.05else:return 0else:return 0# 重构后def calculate_discount(customer):if customer is None:return 0if not customer.is_active:return 0if customer.total_purchases 1000:return 0.1return 0.053.3 用多态替换条件# 重构前def calculate_area(shape):if shape[type] circle:return 3.14 * shape[radius] ** 2elif shape[type] rectangle:return shape[width] * shape[height]elif shape[type] triangle:return 0.5 * shape[base] * shape[height]# 重构后from abc import ABC, abstractmethodclass Shape(ABC):abstractmethoddef area(self):passclass Circle(Shape):def __init__(self, radius):self.radius radiusdef area(self):return 3.14 * self.radius ** 2class Rectangle(Shape):def __init__(self, width, height):self.width widthself.height heightdef area(self):return self.width * self.height四、消除重复代码4.1 提取公共代码# 重构前def send_email_to_customer(customer):email customer.emailsubject Thank youbody Thank you for your purchasesend_email(email, subject, body)def send_email_to_supplier(supplier):email supplier.emailsubject Order placedbody A new order has been placedsend_email(email, subject, body)# 重构后def send_notification_email(recipient, subject, body):send_email(recipient.email, subject, body)def send_email_to_customer(customer):send_notification_email(customer,Thank you,Thank you for your purchase)def send_email_to_supplier(supplier):send_notification_email(supplier,Order placed,A new order has been placed)五、改善命名5.1 使用有意义的名称# 重构前def calc(a, b, c):return a * b * c# 重构后def calculate_volume(length, width, height):return length * width * height5.2 避免魔法数字# 重构前def calculate_price(quantity):if quantity 100:return quantity * 10 * 0.9return quantity * 10# 重构后UNIT_PRICE 10BULK_DISCOUNT 0.9BULK_THRESHOLD 100def calculate_price(quantity):total quantity * UNIT_PRICEif quantity BULK_THRESHOLD:total * BULK_DISCOUNTreturn total六、简化函数参数6.1 使用对象替代参数列表# 重构前def create_user(name, email, age, address, phone, city, country):pass# 重构后from dataclasses import dataclassdataclassclass UserInfo:name: stremail: strage: intaddress: strphone: strcity: strcountry: strdef create_user(user_info: UserInfo):pass6.2 使用关键字参数# 重构前def create_connection(True, False, 30, localhost, 5432)# 重构后def create_connection(sslTrue,verifyFalse,timeout30,hostlocalhost,port5432):pass七、分解大类7.1 提取类# 重构前class Order:def __init__(self):self.items []self.customer_name self.customer_email self.customer_address def add_item(self, item):self.items.append(item)def send_confirmation_email(self):send_email(self.customer_email, Order confirmed)# 重构后class Customer:def __init__(self, name, email, address):self.name nameself.email emailself.address addressclass Order:def __init__(self, customer):self.items []self.customer customerdef add_item(self, item):self.items.append(item)def send_confirmation_email(self):send_email(self.customer.email, Order confirmed)八、移除死代码8.1 删除未使用的代码# 重构前def process_data(data):# old_method(data) # 旧方法已弃用new_method(data)# 这个功能已经不需要了# if data.needs_special_handling:# special_handler(data)# 重构后def process_data(data):new_method(data)九、改善数据结构9.1 用对象替换数据值# 重构前orders [{id: 1, customer: Alice, total: 100},{id: 2, customer: Bob, total: 200}]# 重构后from dataclasses import dataclassdataclassclass Order:id: intcustomer: strtotal: floatorders [Order(1, Alice, 100),Order(2, Bob, 200)]9.2 用枚举替换类型码# 重构前STATUS_PENDING 0STATUS_PROCESSING 1STATUS_COMPLETED 2order_status STATUS_PENDING# 重构后from enum import Enumclass OrderStatus(Enum):PENDING 0PROCESSING 1COMPLETED 2order_status OrderStatus.PENDING十、简化循环10.1 使用列表推导式# 重构前result []for item in items:if item.is_valid():result.append(item.value)# 重构后result [item.value for item in items if item.is_valid()]10.2 使用生成器表达式# 重构前def process_large_file(filename):lines []with open(filename) as f:for line in f:if line.strip():lines.append(line.strip())return lines# 重构后def process_large_file(filename):with open(filename) as f:return (line.strip() for line in f if line.strip())十一、改善错误处理11.1 使用异常而不是返回码# 重构前def divide(a, b):if b 0:return None, Division by zeroreturn a / b, Noneresult, error divide(10, 0)if error:print(error)# 重构后def divide(a, b):if b 0:raise ValueError(Division by zero)return a / btry:result divide(10, 0)except ValueError as e:print(e)11.2 创建自定义异常# 重构前def process_payment(amount):if amount 0:raise ValueError(Invalid amount)if not has_sufficient_funds(amount):raise ValueError(Insufficient funds)# 重构后class PaymentError(Exception):passclass InvalidAmountError(PaymentError):passclass InsufficientFundsError(PaymentError):passdef process_payment(amount):if amount 0:raise InvalidAmountError(Amount must be positive)if not has_sufficient_funds(amount):raise InsufficientFundsError(Insufficient funds)十二、使用上下文管理器# 重构前def process_file(filename):f open(filename)try:data f.read()process(data)finally:f.close()# 重构后def process_file(filename):with open(filename) as f:data f.read()process(data)十三、重构的工具13.1 自动化重构工具- PyCharm内置重构功能- ropePython重构库- autopep8自动格式化- black代码格式化- isort导入排序13.2 代码质量检查- pylint代码质量检查- flake8风格检查- mypy类型检查- bandit安全检查十四、重构的步骤1. 确保有测试覆盖2. 识别代码异味3. 选择重构技术4. 小步重构5. 运行测试6. 提交更改7. 重复以上步骤十五、常见代码异味1. 重复代码2. 过长函数3. 过大类4. 过长参数列表5. 发散式变化6. 霰弹式修改7. 依恋情结8. 数据泥团9. 基本类型偏执10. 过多的条件语句十六、重构的时机1. 添加新功能前2. 修复bug时3. 代码审查时4. 性能优化前5. 定期重构十七、重构的注意事项1. 不要同时重构和添加功能2. 保持小步前进3. 频繁提交4. 确保测试通过5. 与团队沟通6. 记录重构原因十八、总结重构是持续改进代码质量的过程。通过识别代码异味应用合适的重构技术可以使代码更加清晰、易维护。重构应该是日常开发的一部分而不是一次性的大规模改造。保持代码整洁为未来的自己和团队成员创造更好的开发体验。