1. 不with用于打开文件
当您打开一个没有该with语句的文件时,您需要记住close()在完成处理后通过显式调用关闭文件。即使明确关闭资源,在实际释放资源之前也有可能发生异常。这可能会导致不一致,或导致文件损坏。打开文件通过with实现上下文管理器协议,当执行在with块之外时释放资源。
不好的做法:
Python:
new_file = open('some-file.txt', 'r')
# do something exciting
new_file.close()
良好做法:
Python:
with open('some-file.txt', 'r') as fd:
data = fd.read()
# do something exciting
2.使用list/ dict/set理解不必要
内置类似功能all,any,enumerate,iter,itertools.cycle和itertools.accumulate可以直接与发电机表达工作。他们不需要理解。
除了他们,all()并any()在Python也支持短路,但如果使用理解这种行为将丢失。这会影响性能。
不好的做法:
Python:
...
comma_seperated_names = ','.join([name for name in my_fav_superheroes])
良好做法:
Python:
...
comma_seperated_numbers = ','.join(name for name in my_fav_superheroes)
3. 不必要地使用发电机
没有必要在对 的调用中使用生成器表达式list,dict或者set因为对于这些类型中的每一种都有理解。代替使用list/ dict/set周围生成器表达式,它们可以被写为它们各自的理解。
不好的做法:
Python:
squares = dict((i,i**2) for i in range(1,10))
良好做法:
Python:
squares = {i: i**2 for i in range(1,10)}
4. 在函数调用中返回多个对象类型
在函数中具有不一致的返回类型会使代码混乱且难以理解,并可能导致难以解决的错误。如果函数应该返回给定类型(例如整数常量、列表、元组),但也可以返回其他类型,则该函数的调用者将始终需要检查返回值的类型。建议从函数中只返回一种类型的对象。
如果在某些失败的情况下需要返回空的东西,建议引发一个可以干净地捕获的异常。
不好的做法:
Python:
def get_person_age(name):
person = db.get_person(name)
if person:
return person.age # returns an int
# returns None if person not found
良好做法:
Python:
def get_person_age(name):
person = db.get_person(name)
if not person:
raise Exception(f'No person found with name {name}')
return person.age # guaranteed to return int every time
5. 不使用get()从字典中返回默认值
这种反模式会影响代码的可读性。我们经常看到代码创建一个变量,为其分配一个默认值,然后在字典中查找某个键。如果键存在,则键的值被分配给变量的值。这样做虽然没有什么问题,但由于它查询了两次字典,因此冗长且效率低下,而使用get()字典的方法可以轻松完成。
不好的做法:
Python:
currency_map = {'usd': 'US Dollar'}
if 'inr' in currency_map:
indian_currency_name = currency_map['inr']
else:
indian_currency_name = 'undefined'
良好做法:
Python:
currency_map = {'usd': 'US Dollar'}
indian_currency_name = currency_map.get('inr', 'undefined')
6. 不使用items()迭代字典
items字典上的方法返回一个带有键值元组的可迭代对象,可以在for循环中解包。这种方法是惯用的,因此值得推荐。
不好的做法:
Python:
for code in country_map:
name = country_map[code]
# do something with name
良好做法:
Python:
for code, name in country_map.items():
# do something with name
pass
7.不使用文字语法来初始化空list/ dict/tuple
通过调用初始化空字典dict()比使用空字面值要慢,因为名称dict必须在全局范围内查找,以防它被重新绑定。其他两种类型也是如此 -list()和tuple().
不好的做法:
Python:
my_evans = list()
# Add something to this empty list
良好做法:
Python:
my_evans = []
# Add something to this empty list
8. 在生产代码中推送调试器
我们大多数人至少做过一次——在调试代码时,可能会发生在你发现错误后推送代码但忘记删除调试器的情况。这很关键,可能会影响代码的行为。强烈建议在签入之前审核代码以删除调试器的调用。
使用 Python 分析器,您可以在代码库中的所有这些反模式投入生产之前检测它们。