没错,编码风格是一个不太讨巧的话题,不过这里仍然要聊一下。
Python具有其他语言少有的绝佳质量[②](#anchor12):使用缩进来定义代码块。乍一看,似乎它解决了一个由来已久的“往哪里放大括号?”的问题,然而,它又带来了“如何缩进?”这个新问题。
而Python社区则利用他们的无穷智慧,提出了编写Python代码的PEP 8[③](#anchor13)([http://www. python.org/dev/peps/pep-0008/](http://www.python.org/dev/peps/pep-0008/))标准。这些规范可以归纳成下面的内容。
- 每个缩进层级使用4个空格。
- 每行最多79个字符。
- 顶层的函数或类的定义之间空两行。
- 采用ASCII或UTF-8编码文件。
- 在文件顶端,注释和文档说明之下,每行每条`import`语句只导入一个模块,同时要按标准库、第三方库和本地库的导入顺序进行分组。
- 在小括号、中括号、大括号之间或者逗号之前没有额外的空格。
- 类的命名采用骆驼命名法,如`CamelCase`;异常的定义使用`Error`前缀(如适用的话);函数的命名使用下划线分隔的小写字母,如`separated_by_underscores`;用下划线开头定义私有的属性或方法,如`_private`。
这些规范其实很容易遵守,而且实际上很合理。大部分程序员在按照这些规范写代码时并没有什么不便。
然而,**犯错在所难免**,保持代码符合PEP 8规范的要求仍是一件麻烦事。工具**pep8**([https:// pypi.python.org/pypi/pep8](https://pypi.python.org/pypi/pep8))就是用来解决这个问题的,它能自动检查Python文件是否符合PEP 8要求,如示例1.1所示。
**示例1.1 运行pep8**
```
$ pep8 hello.py
hello.py:4:1: E302 expected 2 blank lines, found 1
$ echo $?
1
```
pep8会显示在哪行哪里违反了PEP 8,并为每个问题给出其错误码。如果违反了那些必须遵守的规范,则会报出**错误**(以E开头的错误码),如果是细小的问题则会报**警告**(以W开头的错误码)。跟在字母后面的3位数字则指出具体的错误或警告,可以从错误码的百位数看出问题的大概类别。例如,以E2开头的错误通常与空格有关,以E3开头的错误则与空行有关,而以W6开头的警告则表明使用了已废弃的功能。
社区仍然在争论对并非标准库一部分的代码进行PEP 8验证是否是一种好的实践。这里建议还是考虑一下,最好能定期用PEP 8验证工具对代码进行检测。一种简单的方式就是将其集成到测试套件中。尽管这似乎有点儿极端,但这能保证代码一直遵守PEP 8规范。8.7节中将介绍如何将pep8与tox集成,从而让这些检查自动化。
OpenStack项目从一开始就通过自动检查强制遵守PEP 8规范。尽管有时候这让新手比较抓狂,但这让整个代码库的每一部分都保持一致,要知道现在它有167万行代码。对于任何规模的项目这都是非常重要的,因为即使对于空白字符的顺序,不同的程序员也会有不同的意见。
也可以使用`--ignore`选项忽略某些特定的错误或警告,如示例1.2所示。
**示例1.2 运行pep8时指定`--ignore`选项**
```
$ pep8 --ignore=E3 hello.py
$ echo $?
0
```
这可以有效地忽略那些不想遵循的PEP 8标准。如果使用pep8对已有的代码库进行检查,这也可以暂时忽略某些问题,从而每次只专注解决一类问题。
>注意
> 如果正在写一些针对Python的C语言代码(如模块),则PEP 7([http://www.python.org/dev/ peps/pep-0007/](http://www.python.org/dev/peps/pep-0007/))标准描述了应该遵循的相应的编码风格。
还有一些其他的工具能够检查真正的编码错误而非风格问题。下面是一些比较知名的工具。
- pyflakes(<https://launchpad.net/pyflakes>),它支持插件。
- pylint(<https://pypi.python.org/pypi/pylint>),它支持PEP 8,默认可以执行更多检查,并且支持插件。
这些工具都是利用静态分析技术,也就是说,解析代码并分析代码而无需运行。
如果选择使用pyflakes,要注意它按自己的规则检查而非按PEP 8,所以仍然需要运行pep8。为了简化操作,一个名为flake8(<https://pypi.python.org/pypi/flake8>)的项目将pyflakes和pep8合并成了一个命令,而且加入了一些新的功能,如忽略带有`#noqa`的行以及通过入口点(entry point)进行扩展。
为了追求优美而统一的代码,OpenStack选择使用flake8进行代码检查。不过随着时间的推移,社区的开发者们已经开始利用flake8的可扩展性对提交的代码进行更多潜在问题的检查。最终flake8的这个扩展被命名为hacking(<https://pypi.python.org/pypi/hacking>)。它可以检查`except`语句的错误使用、Python 2与Python 3的兼容性问题、导入风格、危险的字符串格式化及可能的本地化问题。
如果你正开始一个新项目,这里强烈建议使用上述工具之一对代码的质量和风格进行自动检查。如果已经有了代码库,那么一种比较好的方式是先关闭大部分警告,然后每次只解决一类问题。
尽管没有一种工具能够完美地满足每个项目或者每个人的喜好,但flake8和hacking的结合使用是持续改进代码质量的良好方式。要是没想好其他的,那么这是一个向此目标前进的好的开始。
>提示
> 许多文本编辑器,包括流行的GNU Emacs(<http://www.gnu.org/software/emacs/>)和vim(<http://www.vim.org/>),都有能够直接对代码运行pep8和flake8这类工具的插件(如Flycheck),能够交互地突出显示代码中任何不兼容PEP 8规范的部分。这种方式能够非常方便地在代码编写过程中修正大部分风格错误。
这个工具集很容易扩展。我在OpenStack中用`hacking`扩展来扩展这个工具集,例如,我添加了一个检查,用于找出本应该声明为静态的方法。这部分内容会在11.1节中谈及。
> [②](#ac12) 你可能有不同意见。
> [③](#ac13) *PEP 8 Style Guide for Python Code*, 5th July 2001, Guido van Rossum, Barry Warsaw, Nick Coghlan
- 内容提要
- 中文版序
- 前言
- 第1章 项目开始
- 1.1 Python版本
- 1.2 项目布局
- 1.3 版本编号
- 1.4 编码风格与自动检查
- 1.5 Joshua Harlow访谈
- 第2章 模块和库
- 2.1 导入系统
- 2.2 标准库
- 2.3 外部库
- 2.4 框架
- 2.5 Doug Hellmann访谈
- 第3章 管理API变化
- Christophe de Vienne访谈
- 第4章 时区陷阱
- 第5章 文档
- 5.1 Sphinx和reST入门
- 5.2 Sphinx模块
- 5.3 扩展Sphinx
- 第6章 分发
- 6.1 简史
- 6.2 使用pbr打包
- 6.3 Wheel格式
- 6.4 包的安装
- 6.5 和世界分享你的成果
- 6.6 Nick Coghlan访谈
- 6.7 入口点
- 6.7.1 可视化的入口点
- 6.7.2 使用控制台脚本
- 6.7.3 使用插件和驱动程序
- 第7章 虚拟环境
- 第8章 单元测试
- 8.1 基础知识
- 8.2 fixture
- 8.3 模拟(mocking)
- 8.4 场景测试
- 8.5 测试序列与并行
- 8.6 测试覆盖
- 8.7 使用虚拟环境和tox
- 8.8 测试策略
- 8.9 Robert Collins访谈
- 第9章 方法和装饰器
- 9.1 创建装饰器
- 9.2 Python中方法的运行机制
- 9.3 静态方法
- 9.4 类方法
- 9.5 抽象方法
- 9.6 混合使用静态方法、类方法和抽象方法
- 9.7 关于super的真相
- 第10章 函数式编程
- 10.1 生成器
- 10.2 列表推导
- 10.3 函数式函数的函数化
- 第11章 抽象语法树
- 11.1 用抽象语法树检查来扩展flake8
- 11.2 Hy
- 11.3 Paul Tagliamonte访谈
- 第12章 性能与优化
- 12.1 数据结构
- 12.2 性能分析
- 12.3 有序列表和二分查找
- 12.4 namedtuple和slots
- 12.5 memoization
- 12.6 PyPy
- 12.7 通过缓冲区协议实现零复制
- 12.8 Victor Stinner访谈
- 第13章 扩展与架构
- 13.1 多线程的注意事项
- 13.2 多进程与多线程
- 13.3 异步和事件驱动架构
- 13.4 面向服务架构
- 第14章 RDBMS和ORM
- 14.1 用Flask和PostgreSQL流化数据
- 14.2 Dimitri Fontaine访谈
- 第15章 Python 3支持策略
- 15.1 语言和标准库
- 15.2 外部库
- 15.3 使用six
- 第16章 少即是多
- 16.1 单分发器
- 16.2 上下文管理器
- 第17章 延伸阅读
- 版权信息
- 版权声明
- 欢迎来到异步社区!
- 异步社区的来历
- 社区里都有什么?
- 购买图书
- 下载资源
- 与作译者互动
- 灵活优惠的购书
- 纸电图书组合购买
- 社区里还可以做什么?
- 提交勘误
- 写作
- 会议活动早知道
- 加入异步