Effective Python 第一章 总结
第一条
确定使用的python版本,可以通过
1. python –version (对应python3以下的版本)
2. python3 –version (对应python3版本)
第二条
遵循PEP8风格指南
常用的几条:
1.使用空格(每一层缩进常用4个空格)而非制表符
2.占据多行的长表达式,除了首行之外的其余各行应该在通常的缩进级别上再加4个空格。
3.文件中函数与类之间应该用两个空行隔开。
4.在同一个类中,各方法之间应该用一个空行隔开。
5.为变量赋值时,在等号两侧各加一个空格。
6.函数,变量及属性名应该用小写,下划线来表示。 ( lowercase_underscore )
7.受保护的实例属性,以单个下划线开头。( _leading_underscore )
8.私有的实例属性,应该以两个下划线开头。( __double_leading_underscore )
9.类与异常,驼峰命名。(CapitalizedWord)
10.模块级别的常量,全部采用大写字母,单词之间以下划线相连。
11.不要通过检测长度的方法判断元素(比如list,str,tuple)是否为空,而是采用if not list的写法,若list为空会评估为False 。
第三条
了解bytes,str与unicode的区别
在python3中,有2种字符序列类型bytes(原始的8位值)和str(unicode)。
在网络中传输的全是bytes,python3中的str一定为unicode(与python2不同)。
第四条(略)
第五条
了解切割序列的方法
list[start:end:stride]
start:开始的地方(被包含)
end:结束的地方(不被包含)
stride:步进式切割
第六条
不建议在同一次切割中同时使用start/end与stride,会使表达式难读,可以先做步进切割,再做范围切割,或反过来。
第七,八条
用列表推导来取代map和filter
例如:得到原来列表各项平方的新列表
a=[1,2,3,4,5,6,7,8,9,10]
squares = [x**2 for x in a] #squares=[1,4,9,16,25,36,49,64,81,100]
在列表推导时,还可以在循环后面添加条件表达式
squares=[x**2 for x in a if x % 2 ==0] #squares=[4,16,36,64,100]
列表推导还可以采用多重循环:
matrix = [[1,2,3],[4,5,6],[7,8,9]]
flat=[x for row in matrix for x in row] #flat=[1,2,3,4,5,6,7,8,9]
当列表循环条件和循环较多时不易读懂,建议使用if,for并编写辅助函数。
第九条
使用生成器表达式来改写数据量较大的列表推导
列表推导时需要将数据保存到列表中占用内存,当数据量较大时会消耗大量内存,造成程序崩溃。可以使用生成器表达式来代替。
把实现列表推导的写法放在一对圆括号中,就构成了生成器表达式。对生成器表达式进行求值时,会返回一个迭代器。以返回的迭代器为参数,调用next函数可以得到下一个值。
例如:
a=(x for x in range(9))
print(next(a)) #0
print(next(a)) #1
第十条
用enumerate取代range
enumerate提供了一种精简的写法,可以在遍历迭代器的同时获知每个元素的索引。
例如:
li=['a','b','c','d']
for i,word in enumerate(li):
print('%d,%s'%(i,word))
#0,a
#1,b
#2,c
#3,d
还可以指定开始的索引
li=['a','b','c','d']
for i,word in enumerate(li,1):
print('%d,%s'%(i,word))
#1,a
#2,b
#3,c
#4,d
第十一条
用zip函数同时遍历两个迭代器
li1=[1,2,3]
li2=['a','b','c']
for num,word in zip(li1,li2):
print('%d,%s'%(num,word))
#1,a
#2,b
#3,c
当两个迭代器不等长时,遇到短的结束时便结束。
若不能确定zip所封装的列表是否等长,可考虑使用itertools内置模块中的zip_longest函数。
第十二条
不要在for和while循环后写else块
for和while后的else意思是当for或者while循环完毕,中途没有break退出时,就执行else后的部分,否则不执行。注意:若for或者while一次循环也没有执行,看做循环直接就执行0次执行完毕了,因此直接运行else后面的部分。但是这种else怪异并且大部分情况下可以不使用,因此应该避免使用。
第十三条
合理使用try/except/else/finally结构中的每个代码块
1.finally块
try/finally结构,无论try中是否有异常,finally中的部分都要运行。一个常见的应用是确保文件的关闭。
2.else块
try/except/else结构,如果try块没有发生异常,那么就执行else块。
3.混合使用
try/except/else/finally