编写干净的 Python 代码就是要使其尽可能易于理解且简洁。后期便于维护,代码约简洁越好维护,bug就越好排查。
'with’打开文件时使用以确保关闭
在 Python 中打开和使用文件的常用方法是:
file = open("welcome.txt")
data = file.read()
print(data)
file.close() # 这里一定要close
但是,如果在打开和关闭文件之间抛出异常,则最终可能会跳过对 file.close() 的调用。解决此问题的一种方法是使用这样的代码。这里的try…finally结构确保文件将被关闭。
file = open("welcome.txt")
try:
data = file.read()
print(data)
finally:
file.close()
很显然,这种方式很繁琐,虽然这已经解决了文件关闭问题,但它非常冗长。这就是 Python 的with上下文管理器可以派上用场的地方。在幕后,这与try…finally示例的行为方式相同- 一旦退出错,文件就会为您关闭,即使抛出异常也是如此。
with open("welcome.txt") as file:
data = file.read()
print(data)
这段代码更短且更易于阅读 - 让您专注于重要的逻辑而不是文件关闭的细节。
使用默认获取简化字典访问
如果键存在,我们经常想从字典中挑选一些东西,如果不存在,则使用默认值。一种方法是使用这样的条件语句:
def pick_hat(available_hats: Dict[Label, Hat]):
if self.favourite_hat in available_hats:
hat_to_wear = available_hats[self.favourite_hat]
else:
hat_to_wear = NO_HAT
return hat_to_wear
一个有用的快捷方式是 Python 词典有一个get()方法,可以让您使用第二个参数设置默认值。因此,我们可以将上面的代码缩短为:
def pick_hat(available_hats: Dict[Label, Hat]):
hat_to_wear = available_hats.get(self.favourite_hat, NO_HAT)
return hat_to_wear
这减少了代码并删除了一些重复。需要注意的一点是,如果您不传入默认值,它将使用None.
简化负面清单访问
在 Python 中,您可以使用负索引访问列表的末尾。所以my_list[-1]得到最后一个元素,my_list[-2]得到倒数第二个,依此类推。
这意味着你可以把这个:
a = [1, 2, 3]
last_element = a[len(a) - 1]
进入更简单的:
a = [1, 2, 3]
last_element = a[-1]
在保护条件之后删除不必要的 else
一个常见的代码模式是在函数的开始处有一些保护子句,以检查某些条件是否已满足并提前返回或在未满足时引发异常。
def f(a=None):
if a is None:
return 42
else:
# some long calculations
var = (i ** 2 for i in range(a))
return sum(var)
虽然这是完全有效的代码,但它可能会遇到嵌套过多的问题,尤其是在函数的其余部分相当长的情况下。
在这里,我们可以利用这样一个事实,即我们不需要elseif 主体if 以returnor结尾中断控制流raise。重写此处所示的函数在逻辑上是等效的。
def f(a=None):
if a is None:
return 42
# some long calculations
var = (i ** 2 for i in range(a))
return sum(var)
以这种方式使用保护条件或多个保护条件现在不会导致函数的其余部分缩进。一般来说,我们处理缩进的次数越少,代码就越容易理解。
将 for 循环转换为对 sum() 的调用
大部分编程都是关于将事物列表相加,Python 有内置sum()函数来帮助解决这个问题。
您可以for以这种方式重写对列表求和的循环:
前:
total = 0
for hat in hats:
total += hat.price
后:
total = sum(hat.price for hat in hats)
这要短得多,这是一个明确的奖励。代码现在还明确地告诉您它要做什么 - 对所有帽子的价格求和。
将返回提升到 if
这是稍微简化代码的快速方法。在 if 的每个分支上设置一个值然后立即返回,而不是直接从每个分支返回它。
这意味着像这样的代码:
def f():
if condition:
val = 42
else:
val = 0
return val
转换为:
def f():
if condition:
return 42
else:
return 0
这消除了我们必须在心理上跟踪的不必要的中间变量。