python推荐使用3.6以上版本,参考google和PEP8编码风格总结的个人编码经验。
编码原则
- DRY(don’t repeat yourself),不要总是重复自己的代码,抽象问题,提高代码的复用性
- PIE(Program Intently and Expressively), 意图清楚而且表达明确地编程
- ETC(easy to change),代码易于变更,降低模块之间的耦合度,遵循良好的设计模式
命名规范
1.函数使用小写字母+下划线命名,如feature_selection_by_filter,类使用驼峰命名,如DataLoader
2.良好的命名可以向阅读代码的人传递大量的正确信息。 不好的命名不会传递任何信息, 糟糕的命名则会传递错误的信息。对于变量的命名尽量短小并且使用小写字母,可以使用下划线分割多个字母,如sorted_index,sorted_values,也可使用通用或者约定的小写缩写,如df,尽量不用a,b,c,d这种意义不明的单字母命名,禁止使用错误的单词。
3.用单下划线(_)开头表示模块变量或函数是protected的(使用import * from时不会包含) , 用双下划线(__)开头的实例变量或方法表示类内私有。
python之父推荐命名方式
Type | Public | Internal |
---|---|---|
Modules | lower_with_under | _lower_with_under |
Packages | lower_with_under | |
Classes | CapWords | _CapWords |
Exceptions | CapWords | |
Functions | lower_with_under() | _lower_with_under() |
Global/Class Constants | CAPS_WITH_UNDER | _CAPS_WITH_UNDER |
Global/Class Variables | lower_with_under | _lower_with_under |
Instance Variables | lower_with_under | _lower_with_under (protected) or __lower_with_under (private) |
Method Names | lower_with_under() | _lower_with_under() (protected) or __lower_with_under() (private) |
Function/Method Parameters | lower_with_under | |
Local Variables | lower_with_under |
编码规范
1.编写函数体时,要明确输入与输出的类型,如:
def feature_selection_by_filter(method: str, number: int, features: ndarray, labels: ndarray) -> Dict:
2.在文件和sockets结束时, 显式的关闭它, 推荐使用with语句管理文件:
with open("hello.txt") as hello_file:
for line in hello_file:
print line
对于不支持使用with语句的类似文件的对象,使用 contextlib.closing()
:
import contextlib
with contextlib.closing(urllib.urlopen("http://www.python.org/")) as front_page:
for line in front_page:
print line
3.使用json
文件来保存项目中的全局变量,如:
"corpus_save_path": {
"bert_corpus_path": "data/bert_corpus",
"fasttext_corpus_path": "data/fasttext_corpus",
"allennlp_corpus_path": "data/allennlp_corpus",
"tensorflow_corpus_path": "data/tensorflow_corpus"
},
4.使用logger进行日志的记录,可以通过log.conf的配置文件来配置logger。
5.尽量减少try/except块中的代码量。try块的体积越大, 期望之外的异常就越容易被触发。 这种情况下, try/except块将隐藏真正的错误。
6.避免使用监测长度的办法来判断somelist
是否为[]或"等空值,而是采用if not somelist
来判断
7.import语句应该按顺序分为三个部分,分别表示标注库模块、第三方模块以及自用模块
注释
1.函数必须要有文档字符串, 除非它满足以下条件:外部不可见,非常短小,简单明了。 文档字符串应该包含函数做什么,以及输入和输出的详细描述。通常, 不应该描述"怎么做", 除非是一些复杂的算法。文档字符串应该提供足够的信息,当别人编写代码调用该函数时,他不需要看一行代码, 只要看文档字符串就可以了,对于复杂的代码, 在代码旁边加注释会比使用文档字符串更有意义。如:
def feature_selection_by_filter(method: str, number: int, features: ndarray, labels: ndarray) -> Dict:
"""
过滤式特征选择,包括相关系数,卡方检验(CHI2),信息增益(IM-GAIN),互信息(MI,CIFE),基尼指数(GINI)
:param method:特征选择方法,CIFE为升级版的互信息方法
:param number:留下的特征个数
:param features:特征
:param labels:标签
:return:以字典形式返回保留特征的下标以及依据
"""
2.块注释与行注释, 最需要写注释的是代码中那些技巧性的部分, 如果在代码审查的时候必须解释一下, 那应该现在就给它写注释,对于复杂的操作,应该在其操作开始前写上若干行注释,对于不是一目了然的代码,应在其行尾添加注释。如:
# We use a weighted dictionary search to find out where i is in
# the array. We extrapolate position based on the largest num
# in the array and the array size and then do binary search to
# get the exact number.
if i & (i-1) == 0: # true iff i is a power of 2
3.TODO注释, TODO注释应该在所有开头处包含"TODO"字符串,紧跟着是用括号括起来的你的名字,email地址或其它标识符。 然后是一个可选的冒号,接着必须有一行注释, 解释要做什么,主要目的是为了有一个统一的TODO格式,这样添加注释的人就可以搜索到(并可以按需提供更多细节)。写了TODO注释并不保证写的人会亲自解决问题。当写了一个TODO,请注上你的名字。例如:
# TODO(xxx) 简单的对nan值进行了置为0处理,后续需要进行其他更高级的处理
编码小技巧
1.pycharm配置脚本个性化信息
配置样例如下:
# -*- coding:utf-8 -*-
# @author:xxx
# @time:${DATE} ${TIME}
# @desc:
2.在pycharm中按ctrl+shift+L 快速对代码进行排版
3.使用pipreqs生成项目的requirements.txt文件,移动到项目根目录,控制台执行如下命令:
pipreqs ./ --encoding=utf8
4.通过Pylint
可以自动检查受测代码是否符合PEP8
风格,还可以找出代码里的多种常见错误
参考资料