跳转至

02 - 代码质量与规范

目标:写出专业、可维护、高质量的代码

时间:1周学习,终身实践

核心原则:代码是写给人看的,顺便给机器执行


🎯 为什么代码质量重要?

对比

Python
# ❌ 低质量代码
def f(a,b):
    c=0
    for i in range(len(a)):
        if a[i]%2==0:
            c+=a[i]
    return c

# ✅ 高质量代码
def sum_even_numbers(numbers):
    """
    计算列表中所有偶数的和。

    Args:
        numbers: 整数列表

    Returns:
        偶数之和
    """
    return sum(num for num in numbers if num % 2 == 0)

高质量代码的好处

  1. 易读:别人能快速理解
  2. 易维护:修改不容易出错
  3. 易扩展:添加功能更简单
  4. 少bug:清晰的逻辑减少错误

📝 命名规范

变量命名

Python
# ❌ 不好的命名
a = 25  # 年龄?分数?天数?
data = fetch()  # 什么数据?

# ✅ 好的命名
user_age = 25
user_list = fetch_users()

函数命名

Python
# ❌ 不好的命名
def calc(a, b):
    return a + b

def do_something():
    pass

# ✅ 好的命名
def calculate_sum(first_number, second_number):
    """计算两个数的和"""
    return first_number + second_number

def send_email_notification(user_email, message):
    """发送邮件通知给用户"""
    pass

命名规则总结

类型 规则 示例
变量 小写+下划线 user_name, total_count
常量 大写+下划线 MAX_SIZE, PI
函数 小写+下划线 get_user(), calculate_total()
大驼峰 UserManager, HttpRequest
私有 下划线前缀 _internal_var, _private_method()

📝 代码格式

使用工具自动化

Bash
# Python: 使用black格式化
pip install black
black your_file.py

# JavaScript: 使用prettier
npm install --save-dev prettier
npx prettier --write "src/**/*.js"

基本格式规范

Python
# 缩进:4个空格
def example():
    if True:
        print("缩进4个空格")

# 行长度:最多79/88字符
# 长表达式换行
total = (first_number
         + second_number
         + third_number)

# 空行:函数之间2行,类方法之间1行
class MyClass:
    def method1(self):
        pass

    def method2(self):
        pass

# 导入顺序
import os                    # 标准库
import sys

import numpy as np          # 第三方库
import pandas as pd

from mypackage import utils  # 本地模块

📝 注释和文档

什么时候写注释

Python
# ✅ 写注释的情况

# 1. 解释"为什么",而不是"是什么"
# 使用二分搜索因为数据已排序
index = binary_search(sorted_data, target)

# 2. 解释复杂的业务逻辑
# 根据税法第X条,计算应纳税额
tax = calculate_tax(income)

# 3. 标记TODO或FIXME
# TODO: 添加缓存优化性能
# FIXME: 处理边界情况

# ❌ 不要写注释的情况

# 不要解释显而易见的代码
# 设置用户名为"admin"(废话!)
user_name = "admin"

文档字符串(Docstring)

Python
def calculate_bmi(weight, height):
    """
    计算BMI指数。

    BMI(Body Mass Index)是衡量体重是否健康的指标,
    计算公式为:体重(kg) / 身高(m)^2

    Args:
        weight (float): 体重,单位千克
        height (float): 身高,单位米

    Returns:
        float: BMI指数

    Raises:
        ValueError: 如果体重或身高小于等于0

    Example:
        >>> calculate_bmi(70, 1.75)
        22.86
    """
    if weight <= 0 or height <= 0:
        raise ValueError("体重和身高必须大于0")

    return weight / (height ** 2)

📝 函数设计

单一职责原则

Python
# ❌ 一个函数做太多事
def process_user_data(user_data):
    # 验证数据
    if not user_data.get('email'):
        raise ValueError("Email required")

    # 格式化数据
    user_data['name'] = user_data['name'].title()

    # 保存到数据库
    db.save(user_data)

    # 发送邮件
    send_welcome_email(user_data['email'])

# ✅ 拆分成多个函数
def validate_user_data(user_data):
    """验证用户数据"""
    if not user_data.get('email'):
        raise ValueError("Email required")
    return True

def format_user_data(user_data):
    """格式化用户数据"""
    user_data['name'] = user_data['name'].title()
    return user_data

def save_user(user_data):
    """保存用户到数据库"""
    validate_user_data(user_data)
    formatted_data = format_user_data(user_data)
    db.save(formatted_data)
    send_welcome_email(formatted_data['email'])

函数参数

Python
# ❌ 参数太多,难以记忆
def create_user(name, email, age, phone, address, city, country):
    pass

# ✅ 使用对象/字典
def create_user(user_info):
    """
    user_info = {
        'name': 'Alice',
        'email': 'alice@example.com',
        'age': 25,
        ...
    }
    """
    pass

# ✅ 或者使用可选参数
def create_user(name, email, **kwargs):  # *args接收任意位置参数;**kwargs接收任意关键字参数
    """
    create_user('Alice', 'alice@example.com', age=25, phone='123456')
    """
    pass

📝 错误处理

使用异常而不是返回错误码

Python
# ❌ 返回错误码
def divide(a, b):
    if b == 0:
        return -1  # 错误码,容易混淆
    return a / b

result = divide(10, 0)
if result == -1:
    print("Error")

# ✅ 使用异常
def divide(a, b):
    if b == 0:
        raise ValueError("除数不能为0")
    return a / b

try:  # try/except捕获异常
    result = divide(10, 0)
except ValueError as e:
    print(f"Error: {e}")

自定义异常

Python
class ValidationError(Exception):
    """数据验证错误"""
    pass

class NotFoundError(Exception):
    """资源不存在"""
    pass

def get_user(user_id):
    user = db.find(user_id)
    if not user:
        raise NotFoundError(f"用户 {user_id} 不存在")
    return user

📝 代码组织

项目结构

Text Only
my_project/
├── README.md              # 项目说明
├── requirements.txt       # 依赖
├── setup.py              # 安装配置
├── .gitignore            # Git忽略文件
├── src/                  # 源代码
│   ├── __init__.py
│   ├── models/           # 数据模型
│   ├── services/         # 业务逻辑
│   ├── utils/            # 工具函数
│   └── config.py         # 配置
├── tests/                # 测试
│   ├── __init__.py
│   ├── test_models.py
│   └── test_services.py
└── docs/                 # 文档

模块组织

Python
# utils/__init__.py
from .date_utils import format_date, parse_date
from .string_utils import slugify, truncate

# 使用
from utils import format_date

🛠️ 代码审查(Code Review)

审查清单

Markdown
## 代码审查检查表

### 功能性
- [ ] 代码是否实现了需求?
- [ ] 边界条件是否处理?
- [ ] 错误处理是否完善?

### 可读性
- [ ] 命名是否清晰?
- [ ] 函数是否简短?
- [ ] 注释是否必要且清晰?

### 可维护性
- [ ] 是否遵循DRY原则?
- [ ] 是否高内聚低耦合?
- [ ] 是否易于测试?

### 性能
- [ ] 是否有明显的性能问题?
- [ ] 是否有不必要的计算?

✅ 实践建议

每天检查

Markdown
今天写的代码:
- [ ] 我能在3个月后看懂吗?
- [ ] 别人能不问我而看懂吗?
- [ ] 如果出错了,容易定位问题吗?

使用工具

Bash
# Python
pip install black isort flake8 mypy

# 配置pre-commit钩子
pip install pre-commit
pre-commit install

记住:写代码是艺术,好的代码是诗!