在熟悉了python的基本语法后,通过不断地实践,越发地爱上了这门语言。需要深入地理解和用好它。
在学习PEP 8相关文档过程中,获得了一份很好的文档,里面介绍了几个tips,值得python新手进阶的时候学习。
What’s an Idiom
Idioms我觉得在这里叫惯用语最合适,指的是使用python的过程中符合python哲学的“正确”做法。通俗一点可以叫套路,高雅一点可以叫范式。相比错误的做法,采用这些idioms,有以下好处。
- 可读性高
- 执行效率高
- 内存占用少
让程序可执行亦可引入
代码如下:1
if __name__ == '__main__':
这句代码让该脚本能够在cmd中python xxx.py执行,也可以作为一个 module 被别的代码进行import。
正确地判断布尔值
代码如下:1
2if x:
if not x:
不要像C语言那样各种判断,python的数据类型都进行了封装。例如:1
2
3
4
5
6
7
8
9
10# GOOD
name = 'Safe'
pets = ['Dog', 'Cat', 'Hamster']
owners = {'Safe': 'Cat', 'George': 'Dog'}
if name and pets and owers:
print("we have pets")
# NOT SO GOOD
if name != '' and len(pets) > 0 and owers != {}:
print("we have pets")
不必在判断非空这件事情上浪费代码。
使用 in
代码如下:1
2
3
4# container
if item in items:
# iteration
for item in items:
分别举例说明一下。
a. 容器
1 | # GOOD |
这样的写法,阅读很清晰。能够在内置的数据类型中使用(包括列表,字典,集合,字符串)。封装的类,如果实现了contains 方法,也可以实现。
b. 迭代器
1 | # GOOD |
这样的写法,代码更加简洁。同样在内置的数据类型中使用。封装的类,如果实现了iter 方法,也可以实现。这极大地简化了for循环的语句。
交换变量
代码如下:1
a, b = b, a
不必再像C语言使用temp变量进行交换,减少代码。
使用序列生成字符串
代码如下:1
''.join(some_strings)
相比使用+拼接字符串,时间复杂度更低。1
2
3
4
5
6
7
8
9
10
11# GOOD
chars = ['S', 'a', 'f', 'e']
name = ''.join(chars)
print(name)
# NOT SO GOOD
chars = ['S', 'a', 'f', 'e']
name = ''
for char in chars:
name += char
print(name)
捕获异常
代码如下:1
2try:
except:
这里有个概念,鸭子类型(duck typing)。它指的是,如果一个对象,走路像鸭子,叫声像鸭子,那么它一定是鸭子。这是面向对象中的多态(polymorphism)的理论。使用异常而不是使用if来进行各种判断检查,将把我们通过写代码排除各种特殊情况中解放出来。
例如:1
2
3
4
5
6
7
8
9
10
11
12
13# GOOD
d = {'x': '5'}
try:
value = int(d['x'])
except (KeyError, TypeError, ValueError):
value = None
# NOT SO GOOD
if 'x' in d and \
isinstance(d['x'], str) and \
d['x'].isdigit():
value = int(d['x'])
else:
value = None
枚举
代码如下:1
for i, item in enumerate(items):
当既需要遍历容器内的元素,又需要容器内元素的下标时,这个方法便派上用场了。
表达式来构建列表
代码如下:1
[i * 3 for i in data if i > 10]
对于一些比较简单的变换,这种方法非常简洁。如果太复杂,还是使用常规的for+if的语句。我认为判断的依据在于该语句是否太长而影响可读性。
zip创建字典
代码如下1
d = dict(zip(keys, values))
代码简洁,避免使用循环进行创建。
使用 _ 接收无用变量
代码如下:1
for k, _ in [('a', 1), ('b', 2), ('c', 3)]
对于元组中的数值我们不需要,那么使用下划线来接收。如果是以下形式:1
for k, j in [('a', 1), ('b', 2), ('c', 3)]
难免阅读者会去考虑变量j的用途,影响可读性。
总结
这些idioms很有帮助。
1 | if __name__ == '__main__': |
这些我现在已经深刻理解,成为我的python代码风格一部分,
1 | ''.join(some_strings) |
这些我还需要继续熟悉之中。