由于 Python 语言的灵活性,开发者很容易就会写出特别复杂且难以理解的表达式,甚至跨越多行。
下面是一个 URL 查询字符串的解析结果:
>>> from urllib.parse import parse_qs
>>> color_values = parse_qs('red=5&green=&blue=0', keep_blank_values=True)
>>> color_values
{'red': ['5'], 'green': [''], 'blue': ['0']}
解析结果 color_values
是一个以颜色为键,以列表为值的字典。
下面,我们提出一个需求,从字典中提取某种颜色的第一个色彩值,如果该颜色不存在或颜色的值未提供(比如 orange
颜色就不存在,green
颜色的值不存在)那么返回 0 。
根据以上需求,我们很容易就可以写出下面的表达式:
>>> red = int(color_values.get('red', [''])[0] or 0)
>>> green = int(color_values.get('green', [''])[0] or 0)
>>> orange = int(color_values.get('orange', [''])[0] or 0)
>>> red, green, orange
(5, 0, 0)
运行结果是完全正确的,但上述表达式的功能并不是那么一目了然。
下面我们使用条件表达式替代上述的Boolean 表达式:
>>> red = color_values.get('red', [''])
>>> green = color_values.get('green', [''])
>>> orange = color_values.get('orange', [''])
>>> red = int(red[0]) if red[0] else 0
>>> green = int(green[0]) if green[0] else 0
>>> orange = int(orange[0]) if orange[0] else 0
>>> red, green, orange
(5, 0, 0)
我们发现使用 if/else
表达式,要比用 and/or
操作符完成的表达式更加清晰。但在获取多种颜色时,代码显得十分冗长。
下面,我们将获取第一种颜色这段反复使用的逻辑写入辅助函数,提高代码的复用性:
def get_first_int(values, key, default=0):
found = values.get(key, [''])
if found[0]:
found = int(found[0])
else:
found = default
return found
>>> red = get_first_int(color_values, 'red')
>>> green = get_first_int(color_values, 'green')
>>> orange = get_first_int(color_values, 'orange')
>>> red, green, orange
(5, 0, 0)
把复杂的表达式拆成小块,移入辅助函数中之后,整个代码变得非常易读。