针对每条注意点的细节,可以给本篇博客评论,博主本人会针对评论给出示例或相应讲解。
外文文献可参考:Effective Python——59 Specific Ways to Write Better Python, author by Brett Slatkin.
用 Pythonic 方式来思考
1. 了解 bytes、str 和 unicode 的区别
- python 3 中,bytes 是一种包含8位值得序列,str 是一种包含Unicode字符的序列,开发者不能以>或+等操作符来混同操作 bytes 和 str 示例。
- python 2 中,str 是一种包含8位值的序列,unicode 是一种包含 Unicode 字符的序列。如果 str 只含有 7 位 ASCII 字符,那么可以通过相关的操作符来同时使用 str 和 unicode。
- 在对输入的数据进行操作之前,使用辅助函数来保证字符序列的类型与开发者的期望相符。
- 从文件中读取二进制数据,或向其中写入二进制数据时,总应该以 ‘rb’ 或 ‘wb’ 等二进制模式来开启文件。
2. 用辅助函数来取代复杂的表达式
- 开发者很容易过度运用Python的语法特性,从而写出那种特别复杂并且南艺理解的单行表达式
- 请把复杂表达式一如辅助函数中,如果要反复使用相同的逻辑,那就更应该这么做。
- 使用 if/else 表达式,要比用 or 或者 and 这样的 Boolean 操作符写成的表达式更加清晰。
3. 了解切割序列的方法
- 不要写多月的代码:当 start 索引为0,或 end 索引为序列长度时,应该将其省略。
- 切片操作不会计较 start 与 end 索引是否越界,这使得我们很容易就能从序列的前端或后端开始,对其进行范围固定的切片操作(如 a[:20] 或 a[-20:])
- 对 list 赋值的时候,如果使用切片操作,就会把原列表中处在相关范围内的值替换成新值,即便它们的长度不同也依然可以替换。
4. 在单次切片操作内,不要同时指定 start、end 和 stride
- 既有 start 和 end,又有 stride 的切割操作,可能会另人费解。
- 尽量使用 stride 为正数,且不带 start 和 end 索引的切割操作。尽量避免负数作为 stride 。
- 在同一个切片操作内,不要同时使用 start 、end 和 stride。如果确实需要执行这种操作,那就考虑将其拆解为两条赋值语句,其中一条做范围切割,另一条做步进切割,或考虑使用内置 itertools 模块中的 islice。
5. 用列表推导取代 map 和 filter
- 列表推导要比内置的 map 和 filter 函数清晰,因为它无需额外编写 lambda 表达式。
- 列表推导可以跳过输入列表中某些元素,如果改用 map 来做,那就必须以 filter 方能实现。
- 字典与集合也支持推导表达式。
6. 不要使用含两个以上表达式的列表推导
- 列表提到支持多级循环,每一级循环也支持多项条件。
- 超过两个表达式的列表推导是很难理解的,应该尽量避免。