【Python进阶】Pythonic风格整理
所谓Pythonic,就是代码风格符合Python的特点,合理使用“语法糖”,使代码简洁优美,更具可读性,便于维护和修改。
一、Python之禅
Python 里有个小彩蛋:
在 Python Shell 里输入 import this
这段话被称作“Python 之禅”(The Zen of Python),它列举了一些 Python 所推崇的理念,比如:
优美胜于丑陋
明确胜于隐晦
简单胜于复杂
…
可读性很重要
不要忽略错误
面对不确定时,拒绝猜测
现在做好过不做,但盲目动手不如不做
如果你的实现很难说清楚,那是个坏想法;反之亦然
…
我们看一些有经验的工程师写的代码,很容易看出来是出自一个“老手”,那是因为他们的代码比较Pythonic,遵循了一个比较好的代码风格。
“Python 之禅”并不仅限于 Python,很多理念是编程普适的。
下面我列举了一些比较Pythonic的语法实现,主要是从一些大佬的项目中学习并整理的。
普通写法:能实现功能的写法
代码优化:使用Python“语法糖”或其他更具Python风格的写法,使代码更优雅
二、代码对比
1. 实现对列表元素的遍历访问
普通写法
In [1]: lst = ['www.','wenyuanblog','.com']
In [2]: for i in range(len(lst)):
...: print(lst[i])
...:
www.
wenyuanblog
.com
代码优化
In [1]: lst = ['www.','wenyuanblog','.com']
In [2]: for i in lst:
...: print(i)
...:
www.
wenyuanblog
.com
2. 交换两个变量的值
普通写法
In [1]: a = 'hello'
In [2]: b = 'world'
In [3]: temp = a
In [4]: a = b
In [5]: b = temp
In [6]: print(a, b)
('world', 'hello')
代码优化
In [1]: a = 'hello'
In [2]: b = 'world'
In [3]: a, b = b, a
In [4]: print(a, b)
('world', 'hello')
3. 拼接字符串
普通写法
In [1]: letters = ['w', 'e', 'n', 'y', 'u', 'a', 'n', 'b', 'l', 'o', 'g', '.', 'c', 'o', 'm']
In [2]: homepage = ''
In [3]: for letter in letters:
...: homepage += letter
...:
In [4]: print(homepage)
wenyuanblog.com
代码优化
In [1]: letters = ['w', 'e', 'n', 'y', 'u', 'a', 'n', 'b', 'l', 'o', 'g', '.', 'c', 'o', 'm']
In [2]: print(''.join(letters))
wenyuanblog.com
4. 取出列表中大于 0 的元素,生成新列表
普通写法
In [1]: lst = [1, 2, 3, 0, 6]
In [2]: new_lst = []
In [3]: for i in lst:
....: if i > 0:
....: new_lst.append(i)
....:
In [4]: print(new_lst)
[1, 2, 3, 6]
代码优化:列表解析式
In [1]: lst = [1, 2, 3, 0, 6]
In [2]: new_lst = [i for i in lst if i > 0]
In [3]: print(new_lst)
[1, 2, 3, 6]
代码优化:生成器(用于数据量很大,但对新列表仅仅是遍历操作,并不需要一个列表对象的场景)
In [1]: lst = [1, 2, 3, 0, 6]
In [2]: new_lst = (i for i in lst if i > 0)
In [3]: for i in new_lst:
....: print(i)
....:
1
2
3
6
5. 判断一个值是否为True、空列表、None
普通写法
if x == True:
pass
if len(y) == 0:
pass
if z == None:
pass
代码优化
if x:
pass
if not y:
pass
if z is None:
pass
6. 根据键名获取字典中对应的值
普通写法
这样的问题在于,如果 key 不存在,代码就报错跳出。
value = dct[key]
代码优化
改用 get 方法,不存在时会得到 None,或者指定的默认值(这里是 0)。
value = dct.get(key, 0)
7. 持续更新ing
普通写法
代码优化
三、总结
篇幅所限,以上仅仅是一些比较具有代表性的例子。但凡事要有度,过分追求 Pythonic 的写法也可能导致代码的可读性下降。比如有人喜欢把很多功能写在一个语句中,这反倒不 Pythonic 了。所以,我们需要有一些设计的原则,但又不必拘泥于具体的形式,否则就钻入牛角尖了。
平时还是要多看官方库、优秀项目,学习别人的代码。但首先还是要先实现功能,尤其时间紧张的时候,我都会先把功能做出来,然后再去学习、比对、思考,最终优化代码。相信写到足够的代码量后,我们自然而然能“悟道”了。
另外,对于代码本身,Python 有一套书写规范,叫做 PEP8。里面约定了很多细节,比如哪里该空格、注释怎么写、什么地方该换行、如何命名等等。网上搜一下就能找到,还有中文版,务必找时间看一看。