当前位置: 首页 > news >正文

Python代码重构技巧

Python代码重构技巧

一、什么是重构

重构是在不改变代码外部行为的前提下,改善代码内部结构的过程。

1.1 重构的目标

- 提高代码可读性
- 降低代码复杂度
- 提高可维护性
- 消除代码异味
- 为新功能做准备

1.2 重构的原则

- 小步前进
- 频繁测试
- 保持功能不变
- 一次只做一件事

二、提取函数

将复杂的代码块提取为独立的函数。

# 重构前
def process_order(order):
# 计算总价
total = 0
for item in order['items']:
total += item['price'] * item['quantity']

# 应用折扣
if order['customer_type'] == 'vip':
total *= 0.9

# 计算税费
tax = total * 0.1
total += tax

return 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.9
return total

def calculate_tax(total):
return total * 0.1

def 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_suspended

if 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.1
else:
return 0.05
else:
return 0
else:
return 0

# 重构后
def calculate_discount(customer):
if customer is None:
return 0
if not customer.is_active:
return 0
if customer.total_purchases > 1000:
return 0.1
return 0.05

3.3 用多态替换条件

# 重构前
def calculate_area(shape):
if shape['type'] == 'circle':
return 3.14 * shape['radius'] ** 2
elif shape['type'] == 'rectangle':
return shape['width'] * shape['height']
elif shape['type'] == 'triangle':
return 0.5 * shape['base'] * shape['height']

# 重构后
from abc import ABC, abstractmethod

class Shape(ABC):
@abstractmethod
def area(self):
pass

class Circle(Shape):
def __init__(self, radius):
self.radius = radius

def area(self):
return 3.14 * self.radius ** 2

class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height

def area(self):
return self.width * self.height

四、消除重复代码

4.1 提取公共代码

# 重构前
def send_email_to_customer(customer):
email = customer.email
subject = "Thank you"
body = "Thank you for your purchase"
send_email(email, subject, body)

def send_email_to_supplier(supplier):
email = supplier.email
subject = "Order placed"
body = "A new order has been placed"
send_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 * height

5.2 避免魔法数字

# 重构前
def calculate_price(quantity):
if quantity > 100:
return quantity * 10 * 0.9
return quantity * 10

# 重构后
UNIT_PRICE = 10
BULK_DISCOUNT = 0.9
BULK_THRESHOLD = 100

def calculate_price(quantity):
total = quantity * UNIT_PRICE
if quantity > BULK_THRESHOLD:
total *= BULK_DISCOUNT
return total

六、简化函数参数

6.1 使用对象替代参数列表

# 重构前
def create_user(name, email, age, address, phone, city, country):
pass

# 重构后
from dataclasses import dataclass

@dataclass
class UserInfo:
name: str
email: str
age: int
address: str
phone: str
city: str
country: str

def create_user(user_info: UserInfo):
pass

6.2 使用关键字参数

# 重构前
def create_connection(True, False, 30, 'localhost', 5432)

# 重构后
def create_connection(
ssl=True,
verify=False,
timeout=30,
host='localhost',
port=5432
):
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 = name
self.email = email
self.address = address

class Order:
def __init__(self, customer):
self.items = []
self.customer = customer

def 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 dataclass

@dataclass
class Order:
id: int
customer: str
total: float

orders = [
Order(1, 'Alice', 100),
Order(2, 'Bob', 200)
]

9.2 用枚举替换类型码

# 重构前
STATUS_PENDING = 0
STATUS_PROCESSING = 1
STATUS_COMPLETED = 2

order_status = STATUS_PENDING

# 重构后
from enum import Enum

class OrderStatus(Enum):
PENDING = 0
PROCESSING = 1
COMPLETED = 2

order_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 zero"
return a / b, None

result, error = divide(10, 0)
if error:
print(error)

# 重构后
def divide(a, b):
if b == 0:
raise ValueError("Division by zero")
return a / b

try:
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):
pass

class InvalidAmountError(PaymentError):
pass

class InsufficientFundsError(PaymentError):
pass

def 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:内置重构功能
- rope:Python重构库
- 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. 记录重构原因

十八、总结

重构是持续改进代码质量的过程。通过识别代码异味,应用合适的重构技术,可以使代码更加清晰、易维护。重构应该是日常开发的一部分,而不是一次性的大规模改造。保持代码整洁,为未来的自己和团队成员创造更好的开发体验。

http://www.jsqmd.com/news/891060/

相关文章:

  • 多模态深度学习在信贷风控中的应用:BIAF-mDnet框架实战解析
  • 2026年楚雄短视频代运营与GEO优化全攻略:实体店如何用内容获客突破流量困局 - 精选优质企业推荐官
  • AI Code Review 实测:GitHub Copilot PR Review 与 CodeRabbit,能否替代人工 Review?
  • UE5 Niagara新手必看:用条带渲染器给角色加个酷炫拖尾特效(附第三人称蓝图设置)
  • 基于结构化状态空间模型与自监督学习的ECG分析精度提升实践
  • 免费开源文件管理器终极指南:Tablacus Explorer如何彻底改变Windows文件管理体验
  • 收藏|2026 新版零基础学大模型!吃透 AI 应用开发岗,小白 / 程序员转行必看
  • JMeter压测实战:从并发建模到瓶颈定位的完整链路
  • STM32实战:手把手教你给RoboMaster M2006电机调一个稳如老狗的PID(附完整代码)
  • 2026全国五大科研检测机构推荐:2026贵州最新排名出炉,Wela微尔来检测以全维实力领跑 - 十大品牌榜
  • AI赋能出海企业全球化算力调度场景下 云服务器充值的优化路径观察
  • DeepSeek API Key 余额查询 - 图形化界面版本
  • 基于视频会议音频通道的机器人低延迟遥操作技术详解
  • 哪个投票平台最好用?2026年微信投票小程序推荐:中正投票全能首选 - 投票评选活动
  • 国产多模态大模型:如何重塑电商推荐的未来?
  • WinPython终极指南:为什么你的Python环境总是崩溃?这里有解决方案
  • 铁桶厂家的行业资质与认证——偃师市中原制桶有限公司 - 速递信息
  • UGA-GAN:统一几何感知生成对抗网络,解决模式崩溃与几何失真
  • 排污口水质监测管理平台解决方案
  • Nginx监控进阶指南:使用nginx-vts-exporter构建专业级性能监控系统
  • 游戏C#性能监控框架:零GC、低开销、生产级可观测性
  • METS框架:为AI生成文本嵌入可追溯的数字指纹
  • AI不只是聊天机器人了,企业现在更需要什么能力?
  • 2026年5月丽水莲都区黄金回收市场行情全解析与本地变现避坑攻略 - 润富黄金珠宝行
  • 基于模型流体的共沸物分离优化与高效夹带剂筛选方法
  • 【会议征稿通知 | 山东大学主办 | IEEE出版 | EI 、Scopus稳定检索】第八届电子工程与信息学国际学术会议(EEI 2026)
  • 如何在5分钟内掌握ComfyUI IPAdapter Plus图像风格迁移技术
  • 嘉兴2026年5月黄金回收全攻略:实时行情、渠道对比与避坑指南 - 润富黄金珠宝行
  • Apple账户服务端验签原理与合规集成实践
  • k6与Python协同构建自动化性能测试流水线