查看原文
其他

Google | Python编程规范指南

Jackpop 平凡而诗意 2022-08-19

点击蓝字关注我

优秀的代码,不仅仅是实现一个项目、一项功能那么简单,它不仅包含精妙的软件设计模式,还需要依托良好的语言和风格规范。依照编程语言的规范,不仅能够提升代码的可阅读性,还可以提升代码的可靠性,避免因为疏忽细节而造成的不必要错误。本文就结合《Google开源项目风格指南》和日常使用,来抽取出一些比较有用的Python语言规范和风格规范,希望对各位有所帮助。

—▼—

前言

我在前面很多文章中提及过,好的代码绝不仅仅包含能够实现一个项目、一个功能那么简单。在开发一个系统的过程中需要重点考虑代码的可复用性、设计模式,这样能够让后期维护变的更加方便简单。

除了高级的设计模式之外,编程过程中规范的代码也是至关重要的,它不仅能够让周围同事更加容易的阅读和理解、提高团队合作效率,此外,还可以避免因为不规范而造成的细节错误,举个例子,多线程之间存在变量共享问题,如果在写代码时考虑不周到会引起变量的重复写入,进而造成一系列不容被发现的问题。因而,保证良好的开发规范,能够减少很多容易疏忽的错误,为后期代码调试减少很多不必要的工作量。

本文首先介绍一些常用的Python代码分析工具pylint,然后结合《Google开源项目风格指南》提炼、介绍一下Python开发需要着重注意的一些语言规范。

pylint

简介

pylint是一款Python代码分析工具,在企业项目开发部署中,也常用作代码规范的代码的静态检查例如,变量名称格式是否正确检查代码长度等,它的主要功能可以分为如下几个方面:

  • 代码规范

  • 错误检测

  • 协助重构

  • 持续集成

  • ……

其中较为常用的就是代码规范和错误检测,能够按照PEP8编程风格指导对代码进行静态检查,并提示哪里有错误?哪里不够规范?

使用

第一步:首先需要需要按照pylint,

$ pip install pylint

第二步:生成默认配置文件,

$ pylint --persistent=n --generate-rcfile > pylint.conf

然后会生成一个pylint.conf文件,主要包含pylint的一些配置项,这一块可以忽略。

第三步:代码分析

pylint可以单独分析一个文件,也可以分析当前目录下所有子目录的文件,

分析单个文件,

$ pylint test.py

检查、分析单个文件它会详细的列出4个等级的信息报告,分别是,

  • convention

  • refactor

  • warning

  • error

也可以分析整个目录下所有文件,

$ pylint directory_name/

确认后会详细的列出每一个出问题的地方,已经出现了什么问题。

经过pylint的代码分析之后,可以按照它的提示进行修改代码规范,能够极大的提高代码质量。由于pylint是一款很优秀的Python代码静态分析工具,目前很多知名的开发工具都已经集成或者通过简单的配置拥有pylint的功能,例如,pycharm、vscode等。

Google开源项目风格指南

pylint有很多优点,

  • 检查速度快

  • 使用简单

  • 分析深入

  • ……

但是它也有一些不足之处,例如,它严格的按照PEP8进行规范,有很多是不必要的告警,pylint提示的信息过多,这样会无从下手,我们要选择性的抑制或者忽略告警信息。

在很多知名的大企业中都有一套自己的代码开发规范,当然它们很多地方都是有相同之处的,而不是天壤之别的差异。

提高这里就引出了这一节的主角--Google,我们都知道Google是开源社区的主要贡献者之一,它们开源了很多知名且优质的项目,例如,近两年比较火的TensorFlow。它们在开源项目中针对不同语言都有一套明确的风格指南,本文从《Google开源项目风格指南》中提炼出一些比较有价值的Python编程规范,希望能够对各位在Python开发中有所帮助。

Python语言规范

  • 导入包:使用模块全路径来导入包,这样能够避免模块名称相同而造成的冲突
  • 异常处理:首先,raise抛出异常抛出异常时应该使用已有的异常类或者自定义异常类,例如,raise MyException("Error message"),避免抛出一串不知所云的字符串,例如,raise "Error message"。其次,用except捕获异常时避免使用Exception这类泛泛的异常。以上两点主要为了帮助后期调试,能够清楚抛出的什么类型的异常,捕获了什么样的错误,有助于调试。
  • 全局变量:尽量避免使用全局变量,可以用类变量替代。
  • 列表推导:在简单的情况下鼓励使用列表推导式,复杂的情况下避免使用列表推导式,难以阅读,例如,下方,映射表达式, for语句, 过滤器表达式中简单的情形可以用一行列表推导式代替多行代码。
result = []
for x in range(10):
    result.append(x * x)

result = [x ** 2 for x in range(10)]
  • 生成器:生成器可以有效的节省内存占用情况,可以按需使用生成器。
  • 默认参数值:定义一个函数式,我们为了应对某些特例情况而添加几个参数,但是大多数情况下是用不到的,我们可以采用默认参数值的方式应对这些特例调用问题,这里需要注意,默认参数值不要使用可变对象,例如,列表、字典等。
  • True/False的求值:尽量的使用隐式false,在Python中把所有的“空”值,例如,0、None、[]、{}都被认为是false,我们在获取这些返回值时可以用隐式的false,例如,返回的foo是一个空列表,我们可以用if foo:来判断它是否为“空”,而不是if foo==[]:,这样不仅更加易读,而且能够避免犯错。
  • 过时的语言特性:在很多代码里面习惯于使用filter、map、reduce这类语言特性,尽可能使用列表推导或者for循环替代。
以上介绍的是Python在语言方面的规范,也就是说不用这种方式也可以同样实现对应的功能,但是通过上述语言规范能够更多的避免细微之处带来的错误,下面就来介绍一下Python风格规范

Python风格规范

首先来看一下风格这个词汇的概念,

风格是指具有独特于其他人的表现,打扮,行事作风等行为和观念。

也就是说它是一个个性化的概念,对于Python编程,每个人都有自己的风格,你可以按照自己独特的风格去编写代码,这样不会像语言规范那么严格,疏忽之处容易造成错误。Python风格规范更侧重于代码阅读中的地位,良好的风格规范能够让代码更加容易阅读,能够对团队协作、后期维护提供强有力的支撑。

  • 行长度代码行长度不要超过80使用过Pycharm的应该都知道,它有一个代码长度指引线,也就是说按照代码风格规范不要超过这个长度,但是pycharm默认的代码长度是120,这里有一些误导人,在很多大型公司这个数值应该设定为79。pycharm可以通过Editor->Code Style进行修改,vscode可以通过editor.rulers进行设定修改。

  • 括号尽量少使用括号,尤其是在条件语句、返回语句中。

  • 空行顶级定义,例如,函数、类定义之间空两行,类定义和第一个方法、其他方法之间空一行。

  • 空格第一,括号内不要使用空格;第二,不要在逗号、冒号、分号前面加空格,应该在它们后面加上空格;第三、运算符两边加空格。

  • Shebang不要纠结于这个词的含义,它只是一种用法,具体而言,在main主文件前加上#!/usr/bin/python2,或者#!/usr/bin/python3,这是由于#!能够帮助内核找到Python解释器,当然,这只有在执行文件中才有必要,默认main为执行文件。

  • 类继承如果定义的类不从其他类继承,可以显式的从object继承,也就是说用class Sample(object):,而不是class Sample:

  • 字符串避免使用+或者+=累加字符串,由于字符串是不可变对象,如果这样累加会导致创建不必要的临时对象,非线性的增加运行时间。

  • 文件和sockets在文件和sockets结束时,应该显式的关闭它,这里推荐使用with语句,这样就避免重复的写关闭语句,也防止遗忘编写关闭语句。

with open("test.log", 'r') as fp:
    lines = fp.readlines()

  • TODO注释我在前面介绍vs code的文章中提到了TODO注释,这是一个良好的习惯,对临时代码进行TODO注释或者FIXME注释,能够很容易定位到即将解决的问题所在处。

  • 导入模块格式每个导入应该独占一行。

# 正确
import os
import sys

# 错误
import os, sys

  • 命名第一、模块名、包名称、方法名、函数名、实例变量名、函数参数名、局部变量名这些应该使用小写字母加下划线的方式,例如,function_name第二、类名、自定义异常名,应该采用驼峰的命名方式,例如,ClassName第三、全局变量名应该使用大写字母加下划线的方式,例如,GLOBAL_VAL_NAME

注意,Python没有像Java、C++这些严格的受保护变量和私有变量的概念,但是有一些约定成熟的使用方式,例如单下划线(_)用于表示模块变量或者protected变量。双下划线(__)表示实例变量或者类的私有变量。

下面有Python之父Guido推荐的语言规范,

TypePublicInternal
Moduleslower_with_under_lower_with_under
Packageslower_with_under
ClassesCapWords_CapWords
ExceptionsCapWords
Functionslower_with_under()_lower_with_under()
Global/Class ConstantsCAPS_WITH_UNDER_CAPS_WITH_UNDER
Global/Class Variableslower_with_under_lower_with_under
Instance Variableslower_with_under_lower_with_under (protected) or __lower_with_under (private)
Method Nameslower_with_under()_lower_with_under() (protected) or __lower_with_under() (private)
Function/Method Parameterslower_with_under
Local Variableslower_with_under
  • Main:main文件一般用于执行文件,但是这个文件也应该是可以在其他地方导入的,因此需要在main文件中加入if name__ == '__main',这样当直接执行时可以运行主程序,当导入时则不会运行。

结语

上述主要根据《Google开源项目风格指南》提取、总结了一些常用的Python语言规范和风格规范,养成的良好的开发习惯,能够大大减少开发过程中遇到的问题,也许在刚开始去尝试记忆这些事会觉得非常繁琐,但是久而久之、潜移默化之中就养成了这样的习惯,这样就会觉得并不是负担,而且能够提升代码的可靠性和可阅读性。

本文只是抽取了其中部分常用的规范,如果希望进行深入的了解可以访问下方连接查看《Google开源项目风格指南》进行系统学习。

https://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/contents/

END


有趣的灵魂在等你

长按扫码可关注 

相关文章实用工具 | 收下这3款工具,再也不用担心英语翻译!我最终还是选择了VS code!开发工具 | 即将jupyter的新一代notebook效率工具 | 一款基于深度学习的代码自动补全神器强烈推荐 | 竟然有这么优质的github项目!
文章好看就点这里

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存