QMK固件项目Python编码规范详解

QMK固件项目Python编码规范详解

qmk_firmware Open-source keyboard firmware for Atmel AVR and Arm USB families qmk_firmware 项目地址: https://gitcode.com/gh_mirrors/qm/qmk_firmware

前言

在QMK固件项目中,Python代码主要用于构建和测试工具链。为了保持代码的一致性和可维护性,项目制定了一套基于PEP8但有所调整的Python编码规范。本文将深入解析这些规范,帮助开发者编写符合项目要求的Python代码。

基础规范

版本与兼容性

项目明确要求使用Python 3.9版本,以确保在所有支持平台上都能正常运行。这是考虑到不同操作系统可能预装的Python版本差异而做出的决定。

代码缩进

采用4个空格作为缩进标准,这与PEP8规范一致。注意不要使用制表符(Tab),而是使用软制表符(空格)。

注释规范

注释在项目中扮演着重要角色:

  • 应将注释视为描述功能的故事
  • 重点解释"为什么"做出某些决策,而不仅仅是"做什么"
  • 避免显而易见的注释
  • 当不确定注释是否必要时,倾向于添加注释

文档字符串

所有函数都必须包含有用的文档字符串(docstring),这是项目强制要求。文档字符串应清晰描述函数的功能和使用方法。

行长限制

项目对代码行长度持宽松态度:

  • 原则上不强制换行
  • 如需换行,建议不超过76个字符
  • 这种宽松政策是为了提高代码可读性

代码格式化工具

项目推荐使用yapf作为代码格式化工具,并提供了专门的配置文件。yapf可以根据项目规范自动调整代码格式,确保风格统一。

导入规范

导入方式选择

项目没有严格的导入规则,但提供了以下指导原则:

  1. 优先从模块导入特定函数和类名,使代码更简洁
  2. 当导入可能导致名称冲突时,导入整个模块
  3. 避免使用"as"关键字重命名导入,除非导入兼容性模块
  4. 每个模块导入单独一行

导入分组

导入语句应按以下顺序分组:

  1. 系统模块
  2. 第三方模块
  3. 本地模块

禁止的导入方式

明确禁止使用from foo import *这种通配符导入方式,应明确列出需要导入的对象。

导入示例分析

文章提供了多个导入示例,展示了良好和不良的导入实践。关键点是保持代码清晰可读,避免引起混淆。

命名规范

项目采用以下命名约定:

  • module_name:模块名小写,下划线分隔
  • package_name:包名小写,下划线分隔
  • ClassName:类名首字母大写
  • method_name:方法名小写,下划线分隔
  • function_name:函数名小写,下划线分隔
  • GLOBAL_CONSTANT_NAME:全局常量全大写
  • global_var_name:全局变量小写
  • instance_var_name:实例变量小写
  • function_parameter_name:函数参数小写
  • local_var_name:局部变量小写

命名注意事项

  1. 名称应具有描述性,避免缩写
  2. 特别避免使用项目外部人员可能不熟悉的缩写
  3. 文件名应使用.py扩展名,避免使用连字符

应避免的命名

  • 除计数器或迭代器外,避免单字符名称
  • 避免在模块/包名中使用连字符(-)
  • 避免使用双下划线开头和结尾的名称(如__init__)

文档字符串规范

基本格式要求

  1. 使用Markdown格式
  2. 使用三重引号,并至少包含一个换行符
  3. 第一行是简短描述(不超过70字符)
  4. 如需详细说明,在简短描述后空一行
  5. 缩进的行应与开头引号保持相同缩进

内容结构

文档字符串应包含以下部分(如适用):

  1. 函数简短描述
  2. 详细说明(可选)
  3. Args: 参数说明
  4. Returns: 返回值说明
  5. Raises: 可能抛出的异常

各部分之间用空行分隔。

文档字符串示例

文章提供了简单、复杂和带参数说明的三种文档字符串示例,展示了不同情况下的最佳实践。

异常处理规范

  1. 异常应仅用于处理异常情况,而非流程控制
  2. 捕获异常时应处理真正异常的情况
  3. 如使用catch-all异常,必须记录异常和堆栈跟踪
  4. 保持try/except块尽可能短小
  5. 如需大量try语句,应考虑重构代码

数据结构规范

元组

定义单元素元组时必须包含尾随逗号,以明确表示这是元组而非表达式。避免依赖隐式的单元素元组解包。

列表和字典

项目配置了yapf以不同方式处理带尾随逗号的序列:

  • 无尾随逗号:格式化为单行
  • 有尾随逗号:每个元素单独一行

建议短定义保持单行,较长的定义应换行以提高可读性。

其他语法规范

括号使用

避免过度使用括号,但可用括号提高代码可读性。return语句中除非显式返回元组或数学表达式,否则避免使用括号。

字符串格式化

推荐使用printf风格(%操作符)的字符串格式化,这与项目广泛使用的日志模块保持一致,也更符合C程序员的习惯。

推导式与生成器

鼓励使用列表推导式和生成器表达式,但避免过于复杂的表达式。复杂情况下应使用常规for循环。

Lambda函数

允许使用但不鼓励,因为推导式和生成器已能覆盖大多数使用场景。

条件表达式

允许在变量赋值中使用,但应避免在其他场景(如函数参数、序列元素等)中使用,因其可读性较差。

默认参数值

鼓励使用默认参数,但值必须是不可变对象。使用可变对象作为默认值会导致修改在调用间持续,通常不是预期行为。

面向对象规范

属性访问

始终使用@property装饰器而非getter/setter方法。这提供了更Pythonic的接口。

真值判断

在if语句中应优先使用隐式的真值判断,而非显式的True/False比较。

装饰器

在适当场景下使用装饰器,但避免过多"魔法"代码,除非能显著提高可读性。

高级特性限制

项目明确限制使用以下高级特性:

  1. 线程和多进程:通常应避免,如需使用需充分论证
  2. Python高级特性:如自定义元类、字节码访问、动态编译、动态继承等
  3. 类型注解:目前项目不使用任何类型注解系统

这些限制是为了保持代码对非Python专家的可读性和可理解性。

函数设计规范

函数长度

推荐编写小而专注的函数。虽然没有严格限制,但建议:

  • 超过约40行时应考虑拆分
  • 长函数可能隐藏复杂逻辑,增加维护难度
  • 遇到复杂的长函数时,应勇敢重构

代码标记规范

FIXME注释

允许在代码中留下FIXME注释,格式为:

FIXME(用户名): 当某功能完成时重新审视此代码

这种注释有助于标记需要进一步思考或重构的代码区域。

测试规范

项目采用集成测试和单元测试相结合的方式确保代码质量。

集成测试

位于test_cli_commands.py中,通过subprocess运行CLI命令并验证整体行为,检查输出和返回码。

单元测试

其他测试文件包含针对各个模块的单元测试。测试文件命名应与模块名对应(点替换为下划线)。

目前测试套件尚未使用模拟(mocking)技术,欢迎贡献改进。

结语

QMK固件项目的Python编码规范在PEP8基础上进行了适当调整,主要目标是提高代码对非Python专家的可读性。理解并遵循这些规范将有助于开发者贡献高质量的代码,同时保持项目代码风格的一致性。

qmk_firmware Open-source keyboard firmware for Atmel AVR and Arm USB families qmk_firmware 项目地址: https://gitcode.com/gh_mirrors/qm/qmk_firmware

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

劳阔印

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值