Python编码规范
注:此为团队使用的一些规则,非通用规范,通用参考PEP8(2. https://www.python.org/dev/peps/pep-0008/#source-file-encoding)
排版
- 程序块使用缩进风格编写,缩进数为四个空格,不要使用Tab
import语句:
1.每一个模块分行书写 2.三组库的顺序:官方库或模块+pypi上的第三库或模块+本地项目的库或模块,每组库之间加上空格 3.导入库尽量采用绝对路径引用,避免使用from xxx import * 4.django项目同一App内使用显式相对路径导入,django库放在第三方库前面 5.django view视图采用class_based_view风格写,不用函数(https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/)
- 类与类,类与函数,方法与方法之间加上一行空行,
- 两个以上的关键字、变量、常量进行对等或运算操作时,操作符前后加上空格(函数默认参数,”*”,”**”除外)
注释
- 模块注释信息写在最前面
类和函数的注释信息写在定义语句的下一行,前后使用三引号:
1
2
3
4
5
6
7
8
9class A:
"""
xxx
"""
def func():
"""
xxx
"""可以在语句添加一些必要的注释,不要在语句同一行后面添加注释
1
2
3
4def func():
# 这是占位符
pass
pass # 这是占位符,不允许使用
命名
- 模块、包、函数、方法、函数参数、变量使用意思完整的全小写英文描述(单词间可加上下划线),例如webserver或者web_server
- 类名称首字母大写,采用驼峰命名法CapWords风格,例如MyClass
编码
- 对象与None作比较时,使用is/is not,不要用==
- 异常处理采用try…except…except…[else…][finally…)结构(else可省略)
异常捕获要明确处理的是哪种异常 - 获取dict某个键的值采用dict.get(key),不使用dict[key]
- 内部元素确定的序列采用tuple存储
- 列表内的字符串连接采用join方法,不采用切片方式
- 对象类型检查使用isinstance方式,不要type方式
- 序列的复杂处理可以采用推导式,逻辑太复杂的写函数
- 慎用lambda和高阶函数(reduce,map,sort,filter),逻辑太复杂的写函数
- 递归处理不要超过三层
- 功能测试性质的代码放在”if name == ‘main‘:”
logging日志记录模块单文件放置,其他模块引入(from mylogger import logger)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# mylogger.py
import logging
logger = logging.getLogger()
# 先给logger设置一个基础Level,不设置默认为WARNING,重要!
logger.setLevel(logging.DEBUG)
# 创建一个handler,用于写入日志文件
scan_log = logging.FileHandler("scan.log")
scan_log.setLevel(logging.DEBUG)
# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
scan_log.setFormatter(formatter)
# 给logger添加handler
logger.addHandler(scan_log)多线程和多进程使用Queue来协调管理任务和任务间的通信
函数默认参数不要使用list等可变对象(空列表用None代替)
1
2
3
4
5
6
7
8
9def func(bar=None):
if bar is None:
bar = []
bar.append("aaa")
return bar
# 错误方式
def func(bar=[]):
bar.append("aaa")
return bar无关代码但是与模块逻辑有关的需要删除,安全性高的代码打包前需要Cython模块编译为pyd文件,密钥等关键数据建议使用pycryptodome模块加密
http://www.lizenghai.com/archives/898.html- 重复性的代码要封装成可复用的函数和方法