不使用 pythonic 的循环:
l = [1,2,3]#Badfor i in range(0,len(list)): le = l[i] print(i,le)#Goodfor i,le in enumerate(l): print(i,le)
函数调用返回一个以上的变量类型
#Baddef filter_for_foo(l): r = [e for e in l if e.find("foo") != -1] if not check_some_critical_condition(r): return None return rres = filter_for_foo(["bar","foo","faz"])if res is not None: #continue processing pass#Gooddef filter_for_foo(l): r = [e for e in l if e.find("foo") != -1] if not check_some_critical_condition(r): raise SomeException("critical condition unmet!") return rtry: res = filter_for_foo(["bar","foo","faz"]) #continue processingexcept SomeException: #handle exception
循环永不终止
#example:i = 0while i < 10: do_something() #we forget to increment i
不使用 .iteritems() 遍历 dict 的键/值对.
#Badd = { 'foo' : 1,'bar' : 2}for key in d: value = d[key] print("%s = %d" % (key,value))#Goodfor key,value in d.iteritems(): print("%s = %d" % (key,value))
不使用 zip() 遍历一对列表
#Badl1 = [1,2,3]l2 = [4,5,6]for i in range(l1): l1v = l1[i] l2v = l2[i] print(l1v,l2v)#Goodfor l1v,l2v in zip(l1,l2): print(l1v,l2v)
Using "key in list" to check if a key is contained in a list.
This is not an error but inefficient, since the list search is O(n). If possible, a set or dictionary
should be used instead.Note: Since the conversion of the list to a set is an O(n) operation, it should ideally be done only once when generating the list.
#Bad:l = [1,2,3,4]if 3 in l: pass#Goods = set(l)if 3 in s: pass
在循环之后,不使用 'else'.
#Badfound = Falsel = [1,2,3]for i in l: if i == 4: found = True breakif not found: #not found... pass#Goodfor i in l: if i == 4: breakelse: #not found...
对于dict,不使用.setdefault()设置初始值
#Badd = {}if not 'foo' in d: d['foo'] = []d['foo'].append('bar')#Goodd = {}foo = d.setdefault('foo',[])foo.append(bar)
对于dict,不使用.get()返回缺省值
#Badd = { 'foo' : 'bar'}foo = 'default'if 'foo' in d: foo = d['foo']#Goodfoo = d.get('foo','default')
使用map/filter而不是列表解析
#Bad:values = [1,2,3]doubled_values = map(lambda x:x*2,values)#Gooddoubled_values = [x*2 for x in values]#Badfiltered_values = filter(lambda x:True if x < 2 else False,values)#Goodfiltered_values = [x for x in values if x < 2]
不使用defaultdict
#Badd = {}if not 'count' in d: d['count'] = 0d['count']+=1#Goodfrom collections import defaultdictd = defaultdict(lambda :0)d['count']+=1
从一个函数中返回多个值时,不使用命名元组(namedtuple)
命名元组可以用于任何正常元组使用的地方,但可以通过name访问value,而不是索引。这使得代码更详细、更容易阅读。
#Baddef foo(): #.... return -1,"not found"status_code,message = foo()print(status_code,message)#Goodfrom collections import namedtupledef foo(): #... return_args = namedtuple('return_args',['status_code','message']) return return_args(-1,"not found")ra = foo()print(ra.status_code,ra.message)
不使用序列的显式解包
支持解包的序列有:list, tuple, dict
#Badl = [1,"foo","bar"]l0 = l[0]l1 = l[1]l2 = l[2]#Goodl0,l1,l2 = l
不使用解包一次更新多个值
#Badx = 1y = 2_t = xx = y+2y = x-4#Goodx = 1y = 2x,y = y+2,x-4
不使用'with'打开文件
#Badf = open("file.txt","r")content = f.read()f.close()#Goodwith open("file.txt","r") as input_file: content = f.read()
要求许可而不是宽恕
#Badimport osif os.path.exists("file.txt"): os.unlink("file.txt")#Goodimport ostry: os.unlink("file.txt")except OSError: pass
不使用字典解析
#Badl = [1,2,3]d = dict([(n,n*2) for n in l])#Goodd = {n : n*2 for n in l}
使用字符串连接,而不是格式化
#Badn_errors = 10s = "there were "+str(n_errors)+" errors."#Goods = "there were %d errors." % n_errors
变量名包含类型信息(匈牙利命名)
#BadintN = 4strFoo = "bar"#Goodn = 4foo = "bar"
实现java风格的getter和setter方法,而不是使用属性。
#Badclass Foo(object): def __init__(a): self._a = a def get_a(self): return a def set_a(self,value): self._a = value#Goodclass Foo(object): def __init__(a): self._a = a @property def a(self): return self._a @a.setter def a(self,value): self._a = value#Baddef calculate_with_operator(operator, a, b): if operator == '+': return a+b elif operator == '-': return a-b elif operator == '/': return a/b elif operator == '*': return a*b#Gooddef calculate_with_operator(operator, a, b): possible_operators = { '+': lambda a,b: a+b, '-': lambda a,b: a-b, '*': lambda a,b: a*b, '/': lambda a,b: a/b } return possible_operators[operator](a,b)#Badclass DateUtil: @staticmethod def from_weekday_to_string(weekday): nameds_weekdays = { 0: 'Monday', 5: 'Friday' } return nameds_weekdays[weekday]#Gooddef from_weekday_to_string(weekday): nameds_weekdays = { 0: 'Monday', 5: 'Friday' } return nameds_weekdays[weekday]