飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • 第1章 Python简介

    • Python是什么
    • 安装与运行
    • 交互式解释器
    • 注释与编码规范
  • 第2章 变量与数据类型

    • 变量与对象
    • 整数 int
    • 浮点数 float
    • 复数 complex
    • 布尔值 bool
    • 字符串 str
    • 空值 None
    • 类型转换
  • 第3章 运算符与表达式

    • 算术运算符
    • 比较运算符
    • 赋值运算符
    • 逻辑运算符
    • 位运算符
    • 身份与成员运算符
    • 海象运算符
    • 运算符优先级
  • 第4章 流程控制

    • if 语句
    • if-else 语句
    • if-elif-else 语句
    • match-case 语句
    • 条件表达式(三元运算符)
    • while 循环
    • for 循环
    • range 函数
    • break 与 continue
    • 循环的 else 子句
    • pass 语句
  • 第5章 数据结构

    • 列表创建与索引
    • 列表方法
    • 列表推导式
    • 元组
    • 序列解包
    • 集合
    • 字典创建与访问
    • 字典方法
    • 字典推导式
    • range 对象
  • 第6章 函数

    • 定义函数
    • 位置参数与关键字参数
    • 默认参数
    • 可变参数
    • 解包实参
    • 函数返回值
    • lambda 表达式
    • 文档字符串与注解
    • 作用域与命名空间
    • global 与 nonlocal
  • 第7章 模块与包

    • 模块导入
    • 模块搜索路径
    • 包与相对导入
    • 标准库概览
  • 第8章 文件与输入输出

    • 文件读写
    • 上下文管理器
    • 字符串格式化
    • JSON 与 CSV
  • 第9章 面向对象

    • 类与对象
    • 方法
    • 实例变量与类变量
    • 私有变量
    • 继承
    • 多重继承
    • 魔术方法
    • 属性装饰器
    • 数据类 dataclass
  • 第10章 异常处理

    • 语法错误与异常
    • try-except
    • 异常链与 raise
    • 清理操作
    • 自定义异常
  • 第11章 迭代器与生成器

    • 迭代器协议
    • 生成器
    • 生成器表达式
    • 迭代工具
  • 第12章 高级特性

    • 装饰器
    • 函数式编程
  • 第13章 工程实践

    • 测试与调试
    • 代码质量
    • 虚拟环境

代码质量

代码质量决定项目的可维护寿命。高质量的代码不仅运行正确,还要易于阅读、易于修改、易于协作。Python 社区通过 PEP 8 风格指南、静态检查工具和类型注解建立了成熟的代码质量保障体系。

PEP 8 与检查工具

PEP 8 是 Python 官方的代码风格指南,涵盖命名约定、缩进、行长度、空行、导入排序等细节。遵守 PEP 8 不是为了形式,而是为了降低团队阅读代码的认知负担。

核心规范包括:

  • 缩进使用 4 个空格,不用 Tab。
  • 行长度不超过 79 字符(文档字符串/注释不超过 72),现代项目常放宽到 88 或 100。
  • 函数和类之间用两个空行分隔,类内方法之间用一个空行。
  • 导入按标准库、第三方库、本地模块分组,每组之间空一行。
  • 变量用 snake_case,类用 CamelCase,常量用 UPPER_SNAKE_CASE。

pycodestyle(原 pep8)是专门检查 PEP 8 合规性的工具:

python -m pip install pycodestyle
python -m pycodestyle my_module.py
python -m pycodestyle --max-line-length=88 my_module.py

flake8 是更常用的综合检查工具,它集成了 pyflakes(语法和逻辑错误检查)、pycodestyle(风格检查)和 mccabe(圈复杂度检查):

python -m pip install flake8
python -m flake8 src/

flake8 的输出格式为 文件:行:列 错误码 消息。常见错误码:E501(行过长)、W291(行尾空白)、F401(导入未使用)、F821(未定义名称)。通过 setup.cfg 或 pyproject.toml 可以配置忽略项:

[tool.flake8]
max-line-length = 88
extend-ignore = ["E203", "W503"]
max-complexity = 10

E203(冒号前空格)和 W503(换行符前二元运算符)与 black 格式化工具冲突,通常建议忽略。max-complexity 限制函数圈复杂度,超过 10 意味着函数逻辑过于复杂,应拆分。

类型检查:mypy

Python 是动态类型语言,但 PEP 484 引入了类型注解语法,允许开发者为变量、函数参数和返回值标注类型。mypy 是官方推荐的静态类型检查器,它在不运行代码的情况下分析类型一致性,提前发现类型错误:

from typing import List, Dict, Optional, Callable, Tuple

def get_employees_by_dept(
    department: str,
    staff_db: Dict[str, List[str]]
) -> List[str]:
    """返回指定部门的所有员工名字。"""
    return staff_db.get(department, [])

def find_manager(name: str, chain: Dict[str, str]) -> Optional[str]:
    """查找直属领导,可能不存在。"""
    return chain.get(name)

# mypy 会报错:参数类型不匹配
# get_employees_by_dept(123, {})  # error: Argument 1 to "get_employees_by_dept" has incompatible type "int"

Optional[str] 等价于 str | None(Python 3.10+ 写法),表示返回值可能是字符串或 None。mypy 会强制检查调用方是否处理了 None:

manager = find_manager("航仔", {"航仔": "翼王"})
print(manager.upper())          # ❌ mypy 报错:Item "None" of "Optional[str]" has no attribute "upper"

if manager is not None:
    print(manager.upper())      # ✅ 通过检查

函数类型和回调注解:

from typing import Callable

# 标注一个接收两个 float 返回 float 的函数
BinaryOp = Callable[[float, float], float]

def apply_op(a: float, b: float, op: BinaryOp) -> float:
    return op(a, b)

result = apply_op(3.0, 4.0, lambda x, y: x + y)

运行 mypy src/ 即可对整个项目做类型检查。--strict 模式启用更严格的规则(如要求所有函数都加返回类型、禁止隐式 Any),适合追求高可靠性的项目。

文档字符串规范

文档字符串(docstring)是模块、类、函数/方法内部的第一个字符串字面量,可通过 __doc__ 属性访问,被 help()、pydoc 和 Sphinx 等工具提取生成文档。PEP 257 定义了文档字符串的编写规范:

  • 所有公共模块、函数、类、方法都应写文档字符串。
  • 首行是简短摘要,以句号结尾,描述对象的作用而非实现细节。
  • 如果有多行,第二行空行,第三行开始详细说明。
  • 使用三双引号 """ 包裹,即使单行也建议用三引号。

Google 风格文档字符串是业界广泛采用的格式,结构清晰,支持工具自动解析:

def calc_tax(salary: float, rate: float = 0.10, deduction: float = 5000.0) -> float:
    """计算个人所得税。

    根据工资、税率和起征点计算应缴税额。税额可能为负数,
    表示无需缴纳。

    Args:
        salary: 税前月薪。
        rate: 适用税率,默认为 0.10。
        deduction: 起征点,默认为 5000.0。

    Returns:
        计算后的税额(可能为负)。

    Raises:
        ValueError: 当 salary 为负数时抛出。

    Examples:
        >>> calc_tax(18888.0)
        -3111.2
        >>> calc_tax(232000.0)
        18200.0
    """
    if salary < 0:
        raise ValueError("工资不能为负数")
    return salary * rate - deduction

NumPy/SciPy 风格则使用 Parameters、Returns、Raises 等节标题,适合科学计算库。无论采用哪种风格,一致性比风格本身更重要:一个项目内应统一使用同一种格式。

pydocstyle 工具可以检查文档字符串是否符合 PEP 257:

python -m pip install pydocstyle
python -m pydocstyle my_module.py

代码审查清单

代码审查(Code Review)是保障质量的关键环节。以下清单覆盖了 Python 项目中最常见的审查要点:

命名与可读性

  • 变量名是否准确反映其含义?避免 a、tmp、data1 等模糊命名。
  • 函数名是否是动词或动词短语?类名是否是名词?
  • 魔法数字是否提取为命名常量?

函数与类设计

  • 函数长度是否超过 50 行?圈复杂度是否超过 10?
  • 函数参数数量是否过多(超过 4 个建议用数据类或字典)?
  • 类是否遵循单一职责原则?一个类只做一件事。

异常与边界处理

  • 是否捕获了过于宽泛的 except Exception?应捕获具体异常。
  • 文件操作、网络请求、数据库连接是否使用了 try/finally 或上下文管理器?
  • 空值(None、空列表、空字符串)是否被正确处理?

性能与资源

  • 大文件读取是否使用迭代器而非一次性读入内存?
  • 字符串拼接是否在循环中使用了 +=?应改用 str.join()。
  • 字典查找是否替代了列表遍历?(O(1) vs O(n))

测试与类型

  • 新增功能是否配套了单元测试?
  • 类型注解是否覆盖了公共 API?
  • mypy 和 flake8 是否全部通过?

安全

  • 用户输入是否经过校验?是否防范了 SQL 注入和命令注入?
  • 敏感信息(密码、密钥)是否硬编码在源码中?
  • 是否使用了 eval() 或 exec() 处理不可信输入?

将上述清单沉淀为项目的 CONTRIBUTING.md 或检查脚本,配合 CI 自动运行 flake8、mypy 和测试套件,可以在代码合并前自动拦截大部分质量问题。

上一页
测试与调试
下一页
虚拟环境