以下介绍一些python idiom
,每当你在代码库中看到以下的模式可以参照以下的建议进行重构,让代码变得更加的pythonic
,可读性更好,更容易维护。
代码示例Python版本为2.7
enumerate
需要使用列表的下标时,不要使用C风格的下标遍历
1 | lst = ['a', 'b', 'c'] |
1 | # DON'T |
1 | # DO |
zip/izip
同时遍历两个列表时,不要使用C风格的下标遍历
1 | lst1 = ['a', 'b', 'c'] |
1 | # DON'T |
1 | # DO |
1 | # BETTER |
unpacking tuple
swap
1 | x = 10 |
1 | # DON'T |
1 | # DO |
get element from tuple
1 | words = ['apple', 'banana', 'cat'] |
1 | # DON'T |
1 | # DO |
Dict.setdefault/defaultdict
处理字典中key不存在时的默认值
1 | # group words by frequency |
1 | # DON'T |
1 | # DO |
如果你知道自己在做什么,use defaultdict
1 | # BETTER |
Dict.iteritems
遍历字典
1 | words = {'apple': 1, 'banana': 2, 'cat': 3} |
1 | # OK |
1 | # GOOD |
1 | # BETTER |
for...else
break and nobreak
使用for...else
模式处理遍历列表时搜索符合某些条件的元素break
以及搜索不到符合条件元素时的情况。
有些人会认为for...else
的语义让人迷惑所以不建议使用,但是正确地使用for...else
模式会让代码的结构更加清晰。
1 | # search if a word match some condition exists |
1 | # DON'T |
1 | # DO |
else
在for...else
语法里的语义是如果没有break发生
,也即是列表被完全遍历的情况。代码清晰地分成了两部分,你可以明确地看到他们属于同一个结构。
for...else
语法让人迷惑的地方就是在于else
这个名字,根据python核心开发者Raymond Hettinger的说法,如果他们有机会回到过去修改这一语法的话,他们会将else
修改为nobreak
。
事实上如果不需要处理搜索到符合condition元素时的情况,只需要检查符合condition元素是否存在时,使用any
1 | existed = any(map(condition, words)) |
try...except...else
分开异常处理与正常情况
try...except
语法大家都不陌生,大多数情况下简单地使用地try...except...else
语法将臃肿的try block重构就可以让代码的结构更加清晰,将异常处理和正常情况清晰地区分开来。
1 | import json |
1 | # GOOD |
1 | # BETTER |
try...except...else
这个结构清晰地区分了异常可能的抛出点,异常处理及正常情况三种情况。