1.确认自己所使用的python版本
python --version
python3 --version
import sys
print(sys.version_info)
print(sys.version)
2.遵循pep8风格指南
3.了解bytes、str与unicode的区别
def to_str(bytes_or_str):
if isinstance(bytes_or_str, bytes):
value = bytes_or_str.decode(“utf-8”)
else:
value = bytes_or_str
return value
def to_bytes(bytes_or_str):
if isinstance(bytes_or_str, str):
value = bytes_or_str.encode(“utf-8”)
else:
value = bytes_or_str
return value
4.用辅助函数来取代复杂的表达式
red = int(my_values.get(“red”, [’’])[0] or 0)
red = int(red[0]) if red[0] else 0
def get_first_int(values, key, default=0):
found = values.get(key, [’’])
if found[0]:
found = int(found[0])
else:
found = default
return found
5.了解切割序列的办法
切片操作的start和end索引越界不引起错误
对list赋值的时候,如果使用切片操作,会把原列表中处在相关范围内的值替换成新值
6.在单次切片操作内,不要同时指定start、end和stride
在同一个切片操作内,不要同时使用strat、end和stride。如果确实需要执行这种操作,
那就考虑把将其拆解为两条赋值语句,其中一条做范围切割,另一条做步进切割,或考虑使用内置itertools模块种的islice。
7.用列表推导来取代map和filter
列表推导要比内置的map和filter函数清晰,因为它无需额外编写lambda表达式
8.不要使用含有两个以上表达式的列表推导
超过两个表达式的列表推导是很难理解的,应该尽量避免
9.用生成器表达式来改写数据量较大的列表推导
由生成器表达式所返回的迭代器,可以住此产生输出值,从而避免了内存用量的问题。
it = (len(x) for x in open(’/tmp/my_file.txt’))
10.尽量用enumerate取代range
test = [‘1’, ‘2’, ‘3’]
for i, num in enumerate(test):
print (’%d: %s’ % (i+1, num))
尽量使用enumerate改写哪种将range与下表访问结合的序列遍历代码
11.用zip函数同时遍历两个迭代器
内置的zip函数可以平行地遍历多个迭代器
如果提供的迭代器长度不等,那么zip就会自动提前终止
12.不要在for和while循环后面写else块
python中只有当整个循环主体都没遇到break语句时,循环后面的else块才会执行。
13.合理利用try/except/else/finally结构中的每个代码块
else块可以处理没有发生异常时候的执行语句
finally语句无论发生还是不发生异常都会执行
顺利运行try后,在执行finally之前,可以采用else来执行某些操作
14.尽量用异常来表示特殊情况,而不要返回None
函数在遇到特殊情况时,应该抛出异常,而不要返回None
15.了解如何在闭包里使用外围作用域中的变量
对于定义在某作用域内的闭包来说,它可以引用这些作用域中的变量
使用默认方式对闭包内的变量赋值,不会影响外围作用域中的同名变量
python3中可以使用nonlocal语句来修饰某个名称,使该闭包可以修改外围作用域中的同名变量
python2中可以采用可变值来实现与nonlocal语句相仿的机制
除了比较简单的函数,尽量不要使用nonlocal
16.考虑用生成器来改写直接返回列表的函数
使用生成器比把收集到的结果放入列表里返回给调用者更加清晰
由生成器函数所返回的那个迭代器,可以把生成器函数体中,传给yield表达式的那些值,逐次产生出来
如何判断一个函数是否是一个特殊的 generator 函数?可以利用 isgeneratorfunction 判断:
清单 7. 使用 isgeneratorfunction 判断
1
2
3
from inspect import isgeneratorfunction
isgeneratorfunction(fab)
True
17.在参数上面迭代时,要多加小心
把__iter__方法实现为生成器,即可定义自己的容器类型
18.用数量可变的位置参数减少视觉杂讯
调用函数时,可以采用*操作符,把序列中的元素当成位置参数,传给该函数
19.用关键字参数来表达可选的行为
函数参数可以按位置或者关键字位置来指定
20.用None和文档字符串来描述具有动态默认值的参数
参数的默认值,只会在程序加在模块并读到本函数的定义时评估一次。对于{}或[]等动态的值,这可能会导致奇怪的行为
对于以动态值作为实际默认值的关键字参数来说,应该把形式上的默认值写为None,并在函数的文档字符串里面描述该默认值所对应的行为
21.用只能以关键字形式指定的参数来确保代码的明晰
22.尽量用辅助类来维护程序的状态,而不要用字典和元组
不要使用包含其他字典的字典,也不要使用过长的元组
如果容器中包含简单而又不可变的数据,那么可以先使用namedtuple来表示,稍后有需要时,在修改为完整的类
23.简单的接口应该接受函数,而不是类的实例
24.以@classmethod形式的多态去通用的构建对象
25.用super初始化父类