python风格指南

前言

本文包含代码风格、Python特性使用、面对不同问题的最佳解决方案三大块内容

代码风格是指编写代码过程当中的排版布局的问题,主要是PEP8当中的一些内容,针对PEP8我自己加了一些认为自己需要注意的点进去

Python特性使用是指对于写Python的过程当中

代码风格

空行

  1. 模块顶级元素(类、函数)之间空两行
  2. 类中的方法之间空一行
  3. 其他认为有必要空行以分割逻辑块的地方空一行,不对对于逻辑快的区分优先使用函数解构的方法去做

导入

  1. 引用层次依次为标准库的引用>第三方库的引用>项目内引用,不同引用层次之间空一行以表示区隔
  2. 一般情况下不使用 from module import * 的写法
  3. 仅在引用核心模块的时候使用 from module import something 的写法,对于非核心模块,均使用 import module
  4. 可以在要引用的模块名过长的时候使用 import module as mod 这样的写法

缩进

  1. 用四个空格来缩进代码
  2. 优质的分行缩进方式范例
../_images/5A4787FE-BAF6-4E07-A355-5DC9361570C2.png

换行

  1. 可以通过首个元素就换行来解决对齐问题

Shebang

Shebang亦即 #! ,只有被直接执行的文件才有必要加入

行长度

除了导入模块的语句,每行代码不超过80个字符

长表达式

  1. 对于调用链使用如下的拆分方案
pagination = db.session.query(Vocabulary).\
filter_by(user_id=user_id, is_remember=False).\
paginate(page, per_page=20, error_out=False)
  1. 对于多参数使用如下的拆分方案
new_word = Vocabulary(
    user_id=request_content['user_id'],
    word=request_content['word'],
    word_explain=request_content['explain']
)

注释

  1. 函数或方法的docstring
  2. 类的docstring
  3. 块注释
  4. 行注释:不要使用行注释,全部用块注释代替,#后面要加空格

命名

  1. 对于不希望外部使用的模块变量或函数使用单下划线(使用 import * from 的时候不会被包含)
  2. 不要使用双下划线
  3. 对于模块名使用小写加下划线的方式

Main

所有的可执行代码都应该使用 if __name__=='__main__' 来包含可执行代码块,防止其被导入的时候产生副作用

引号

使用单引号而非双引号

功能使用

匿名函数

一般情况下,仅在参数需要可调用对象的时候使用使用匿名函数

在这种情况下,匿名函数的好处在于有些函数支持传入可调用对象,但不支持传入可调用对象的参数,这种方式可以解决这个问题

异常

  1. 异常的触发必须使用这种形式: raise MyException("Error message") 或者 raise MyException
  2. 模块和包定义自己的异常基类的时候应用从内建的Exception类继承(这个我暂时还用不上)
  3. 如非必要,永远不要使用 except 或者 except Exception 这种来捕获所有的异常,前者比后者更加难以容忍,甚至会捕获KeyboardInterrupt
  4. try块中的语句要尽量小,只包含你想要捕获异常的语句
  5. 使用finally子句来执行哪些无论try快中有没有异常都应该被执行的代码
  6. 异常的使用规范
../_images/93BBEB2A-D51E-40CC-AED0-8443807DAC56.png

我选择前者,更多使用异常处理而非条件判断

全局变量

避免使用全局变量,用类变量来代替除非在以下情况下:

  1. 模块级常量

列表推导

  1. 使用列表推导以代替map()和filter()
  2. 不要滥用列表推导,列表推掉的使用前提是使代码显得清晰明确,如果有双重循环或者列表推导的长度过长,那么就不要去使用列表推导,而是应当直接使用循环

生成器

  1. 对于要存储量大的数据,鼓励使用生成器(迭代器)
  2. 生成器的意义在于其惰性产出值从而节省内存,如果一个生成器对象包含一个列表作为属性的话,那么就没有什么意义了

特性(properties)

  1. 使用 @property 装饰器来进行创建
  2. 代替java当中那种烦人的get和set方法,维护接口的统一性
  3. 可拓展性强,刚开始可以不使用特性,想用特性的时候又不会破坏原有的接口

函数参数

  1. 尽量不要在参数列表中加复杂的对象(尽量只加基础对象)
  2. 对于比较复杂的数据的情况,可以使用嵌套的元组、字典
  3. 永远不要修改修改或保存传入的数据,对于可变对象而言,一定要复制一个副本,而非在元对象的基础上做改变

文件命名

1. python相关的文件统一使用下划线进行命名 2.

最佳实践

log

  1. 日志的使用
../_images/BABE5B3A-2A49-4302-8DEF-24F4C2ED9408.png

陷阱

使用可变对象作为默认参数值

幽灵bus的阴影

用if去判断函数返回值是否为None

../_images/71455833-1590-4C6F-9AEF-A39DAF52D7C8.png