Python编码规范(PEP8)
本文主要讲解Python编码规范(PEP8)相关知识点
问题:列举几条PEP8编码规范
1.使用4个空格进行缩进,建议不要使用制表符(tab)
2.文件中函数与类之间应该用两个空行隔开,使代码结构更加清晰
3.每行代码长度不超过79个字符,对于长的表达式应适当换行
4.在运算符前后加上空格,但不要过度空格化
5.使用全小写字母和下划线命名变量、函数和模块
6.import语句应该总是放在文件开头,且一行导入一个库包
7.尽量使用英文写代码注释
8.在使用下标来获取列表元素、调用函数或给关键字参数赋值的时候,不要在两旁添加空格
9.变量赋值时,赋值符号左右两侧各自加一个空格
10.使用描述性和有意义的单词去命名变量、方法和函数
遵循代码规范的好处
① 良好的代码规范可以使代码风格保持一致性,对于一个函数、模块或者项目,代码风格一致非常重要
② 良好的代码规范可以提升代码的可读性
可以忽略代码规范的场景
① 与项目或团队代码保持一致
② 遵循代码规范后可读性变差
③ 需要兼容不支持代码规范的老版本Python
许多项目有自己的编码规范,在出现规范冲突时,项目自身的规范优先
有时候编码规范的建议并不适用,当存在模棱两可的情况时,使用自己的判断
代码布局
布局清晰、整洁、优雅的代码方便阅读,有利于团队之间的沟通。代码不是能工作就行,代码要可维护、可扩展
① 缩进
每一级缩进使用4个空格(首选)
Python使用严格的代码缩进方式分隔代码块
制表符只能用于与同样使用制表符缩进的代码保持一致
不允许同时使用空格和制表符的缩进
续行应该与其包裹元素对齐,当使用挂行缩进时,应该考虑到第一行不应该有参数,以及使用缩进以区分自己是续行
# 与左括号对齐 foo = long_function_name(var_one, var_two, var_three, var_four) # 用更多的缩进来与其他行区分 def long_function_name( var_one, var_two, var_three, var_four): print(var_one) # 挂行缩进应该再换一行 foo = long_function_name( var_one, var_two, var_three, var_four)
② 行的最大长度
所有行限制的最大字符数为79
没有结构化限制的大块文本(文档字符或者注释),每行的最大字符数限制在72
# 推荐
with open('/path/to/some/file/you/want/to/read') as file_1, \
open('/path/to/some/file/being/written', 'w') as file_2:
file_2.write(file_1.read())
# 不推荐: 操作符离操作数太远
income = (gross_wages +
taxable_interest +
(dividends - qualified_dividends) -
ira_deduction -
student_loan_interest)
# 推荐:运算符和操作数很容易进行匹配
income = (gross_wages
+ taxable_interest
+ (dividends - qualified_dividends)
- ira_deduction
- student_loan_interest)
③ 插入空行
函数和函数,函数和类之间的分隔,前后用两个空行隔开
class MyFirstClass:
pass
class MySecondClass:
pass
def top_level_function():
return None
类里的方法定义用一个空行隔开
class MyClass:
def first_method(self):
return None
def second_method(self):
return None
变量赋值和导入声明之间插入空行,分隔语义
注意有关联的代码要保持紧凑,比如if和else之间就没有必要插入空行
④ imports导入
一行导入一个函数库包
导入总是位于文件的顶部,在模块注释和文档字符串之后,在模块的全局变量与常量之前
# 推荐
import os
import sys
# 不推荐
import os, sys
# 可以一个包中导入多个子模块
from urllib import request, parse
避免通配符的导入
# 不推荐
from numpy import *
因为这样做会不知道命名空间中存在哪些名字,会使得读取接口和许多自动化工具之间产生混淆
文件中的import 按顺序导入分成三部分(标准库,三方库,自用),每部分按字母顺序排序
⑤ 表达式和语句中的空格
1.避免使用无关的空格的场景:
紧跟在小括号,中括号或者大括号后
# Yes spam(ham[1], {eggs: 2}) # No spam( ham[ 1 ], { eggs: 2 } )
紧贴在逗号、分号或者冒号之前
# Yes if x == 4: print x, y; x, y = y, x # No if x == 4 : print x , y ; x , y = y , x
紧贴在函数参数的左括号之前
# Yes spam(1) # No spam (1)
紧贴索引或者切片的左括号之前
# Yes dct['key'] = lst[index] # No dct ['key'] = lst [index]
2.总是在二元运算符两边加一个空格:
赋值(=)
增量赋值(+=,-=)
比较(==,<,>,!=,<>,>=,in,not,is等)
布尔(and,or,not)
如果使用具有不同优先级的运算符,请考虑在具有最低优先级的运算符周围添加空格,有时需要通过自己来判断。但是,不要使用一个以上的空格,并且在二元运算符的两边使用相同数量的空格
# 推荐
i = i + 1
submitted += 1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)
# 不推荐
i=i+1
submitted +=1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)
3.在指定关键字参数或者默认参数的时候,不要在=附近加上空格
# 推荐
def complex(real, imag=0):
return magic(r=real, i=imag)
# 不推荐
def complex(real, imag = 0):
return magic(r = real, i = imag)
4.避免同一行中存在多个语句
# 推荐
def fn(num):
return num
# 不推荐
def fn(num): return num
命名规范
1.使用英文单词命名
2.不要害怕过长的命名变量,写的越清楚越好
3.避免重复使用变量名表示不同的对象
4.不能使用内建名称,使其在当前命名空间被屏蔽
5.避免使用字母o(与数字0混淆),和字母l(与数字1混淆)
6.使用下划线分隔小写单词以提高可读性
编写可读代码的关键之一是使用描述性和有意义的变量名,这将使其他人更容易理解你的代码
# Not recommended(反例)
x = 'John Smith'
y, z = x.split()
print(z, y, sep=', ') # Smith, John
# Recommended(正例)
name = 'John Smith'
first_name, last_name = name.split()
print(last_name, first_name, sep=', ') # Smith, John
与使用描述性变量名类似,使用描述性函数和方法名可以使你编写的代码更易于理解和维护
类型 | 命名约定 | 例子 |
Module | 使用小写字母;下划线分隔单词 | module.py my_module.py |
Package | 使用小写字母;不用下划线分隔单词 | package mypackage |
Class | 每个单词首字母大写,不要使用下划线 | MyClass |
Function | 使用小写字母;下划线分隔单词 | function my_function |
Constant | 使用大写字母;下划线分隔单词 | MAX_OVERFLOW TOTAL |
Variable | 使用小写字母;下划线分隔单词 | username my_variable |
Method | 使用小写字母;下划线分隔单词 | calss_method method |
我们可以使用不同的命名风格区分不同的类型变量,例如可以使用大写字母UPPERCASE或者使用下划线风格的大写字母UPPER_CASE_WITH_UNDERSCORES表示常量(Constant)
变量名(Variable)只能包含小写字母,名称中的任意两个单词用下划线分隔
# Proper variable name
employee_names = ["vikash", "Shreya", "Abdul"]
# Improper variable name
Employee_Names = ["vikash", "Shreya", "Abdul"]
# Improper variable name
EMPLOYEE_NAMES = ["vikash", "Shreya", "Abdul"]
函数名(Function) 如果有多个单词,函数名应该只包含小写字母并用下划线分隔,不包括任何大写字母
# Proper function name
def count_numbers():
pass
# Improper function name
def Count_Numbers():
pass
# Improper function name
def CountNumbers():
pass
类名(Class) 如果有多个单词,每个单词首字母都需要大写,不要使用下划线
# Proper name
class Vehicles:
pass
# Another proper name CapWords style
class NewVehicles:
pass
注意:当在首字母大写的风格中用到缩写时,所有缩写的字母用大写,因此HTTPServerError比HttpServerError好
注释原则
注释就是对代码的解释和说明,其目的是让人们能够更加轻松地了解代码
与代码相矛盾的注释比没有注释还糟糕,当代码更改时,优先更新对应的注释!
注释应该是完整的句子。如果一个注释是一个短语或句子,它的第一个单词应该大写,除非它是以小写字母开头的Python标识符(永远不要改变标识符的大小写!)
尽量使用英文写注释(除非特殊情景)
注释分类
① 块注释
② 行内注释
③ 文档注释
块注释
块注释用于解释后续代码的作用,通常块注释的缩进和代码块保持一致
块注释的每一行开头使用一个#和一个空格(除非块注释内部缩进文本)
块注释一般由完整句子的一个或多个段落组成,并且每句话结束有个句号.
# Price increase by 5 percent.
price = price * 1.05
块注释缩进到与被描述的代码相同的级别,如果注释较多,也可以对注释分段
def quadratic(a, b, c, x):
# Calculate the solution to a quadratic equation using the quadratic
# formula.
#
# There are always two solutions to a quadratic equation, x_1 and x_2.
x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)
return x_1, x_2
行内注释
行内注释是与代码语句同行的注释,行内注释和代码至少要有两个空格分隔,注释由#和一个空格开始(我们需要有节制地使用行注释)
x = x + 1 # Compensate for border
使用块注释或者行注释的时候仅仅注释那些复杂的算法或操作以及别人难以理解的技巧或不够一目了然的代码
文档注释
文档注释要为所有的公共模块,函数,类以及方法编写文档说明。非公共的方法没有必要,但是应该有一个描述方法具体作用的注释,这个注释应该在def那一行之后
文档注释要描述方法的功能、对参数、返回值和可能的异常进行说明,目标就是让使用这个方法的人仅看文档就知道正确用法
单行文档注释是指只有一行的文档注释,使用三双引号(""")开始,使用三双引号(""")结束
单行文档注释的前后没有任何空行
def quicksort():
""" sort the list using quicksort algorithm """
pass
多行文档注释可以包含多行注释文本。多行文档注释也是使用三双引号(""")开始,使用三双引号(""")结束
特别需要注意的是,多行文档注释说明使用的结尾三双引号应该自成一行
def increase(salary, percentage, rating):
""" increase salary base on rating and percentage
rating 1 - 2 no increase
rating 3 - 4 increase 5%
rating 4 - 6 increase 10%
"""
pass
代码注释注意事项
注释和代码要隔开一定的距离
注释应该用来解释代码的功能、原因和想法,不是对代码本身的解释
不要使用注释来删除代码,不要的代码直接删除,不要将其注释掉!
注释关系到代码的可读性和可维护性,不要懒得去写,代码更新也要及时更新注释
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)