part 1. 用Pythonic的方式思考
-
确认自己所用的python版本(使用python3.x)
-
遵循PEP8风格指南
- 使用space来表示缩进,而不要使用tab,和语法相关的每一层缩进都用4个空格来表示
- 其他的PEP8风格标准可以通过Pycharm自带的风格修正来完成(Reformat File)
- 函数、变量以及属性应该用小写字母来拼写,各单词之间用下划线连接,如:lowercase_underscore
- 受保护的实例属性应该以单个下划线开头,如:_leading_underscore
- 私有的实例属性应该以两个下划线开头,如__double_leading_underscore
- 类与异常应该以每个单词首字母大写的形式命名,如GradeBook
- 模块级别的常量应该全部采用大写字母拼写,各单词之间用下划线连接,如ALL_CAPS
- bytes、str、unicode的区别
-
编写python程序时,要把编码和解码工作放在界面的最外围来做
-
#接受str或bytes,返回str def to_str(bytes_or_str): if isintance(bytes_or_str, bytes): value = bytes_or_str.decode('utf8') else: value = bytes_or_str return value #接受str或bytes,返回bytes def to_bytes(bytes_or_str): if isinstance(bytes_or_str): value = bytes_or_str.encode('utf8') else: value = bytes_or_str return value
-
用’wb’或’rb’来以二进制格式来开启并读写文件
- 用辅助函数来取代复杂的表达式
- 将复杂的表达式移入辅助函数之中,特别是在要反复使用同样的逻辑的时候
- 使用if/else表达式要比用or/and这样的布尔操作符写成的表达式更加清晰
- 切割序列的方法
- 切割格式:[start : end : stride]
- start为开始索引,涵盖在切割后的范围中;end为结束索引,所指的元素不包含在切割结果中
- 切割列表时,即使start或end索引越界也不会出现问题,但访问列表中的单个元素时下标越界会导致异常
-
在单词切片操作内,不要同时指定start、end和stride
-
用列表推导来取代map和filter
-
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] squares = [x**2 for x in a] print(squares) #输出[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
-
使用map需要创建lambda函数,以便计算新列表中各个元素的值
-
列表推导可以跳过输入列表中的某些元素,如果改用map来做,那就必须辅以filter才能实现
- 不要使用含有两个以上表达式的列表推导
- 列表推导支持多级循环,每一级循环也支持多项条件,但超过两个表达式的列表推导是很难理解的,应该尽量避免
- 用生成器表达式来改写数据量大的列表推导
-
列表推导在推导的过程中,对于输入序列中的每个值来说可能都要创建仅含一项元素的全新列表,输入数据较多的时候可能会因为消耗大量内存引起程序崩溃
-
生成器表达式在运行的时候并不会把整个输出序列都呈现出来,而是会估值为迭代器,每个迭代器每次可以根据生成器表达式产生一项数据。对生成器求值时,它会立刻返回一个迭代器而不会深入处理文件中的内容
-
#列表推导式 value = [len(x) for x in open('test.txt')] print(value) #生成器表达式 it = (len(x) for x in open('test.txt')) print(next(it))
- 尽量使用enumerate取代range
-
python提供了内置的enumerate函数,可以把各种迭代器包装为生成器,以便稍后产生输出值。生成器每次产生一对输出值,其中前者表达循环下标,后者表示从迭代器中获取到的下一个序列元素
-
for i, flavor in enumerate(flavoe_list): print('%d: %s' % (i + 1, flavor))
- 用zip函数同时遍历两个迭代器
-
for name, count in zip(names, letters): if count > max_letters: longest_name = name max_letters = count
-
受封装的迭代器中只要有一个耗尽,zip就不再产生新元组。若不能确定zip所封装的列表是否等长,则可以使用itertools内置模块中的zip_longest函数
-
不要在for和while循环后面写else块(一般不会这么写吧)
-
合理利用try/except/else/finally结构中的每个代码块
-
finally块(常见用途:确保关闭文件句柄):
handle = open('test.txt') try: data = handle.read() finally: handle.close() #文件成功打开则一定能执行
-
else块:
def load_json_key(data, key): try: result_dict = json.loads(data) except ValueError as e: raise KeyError from e else: return result_dict[key]