Item 5: Write Helper Functions Instead of Complex Expressions(编写辅助函数,而不是复杂的表达式)

Python简洁的语法使编写实现大量逻辑的单行表达式变得容易。
例如,假设我想解码来自URL的查询字符串。这里,每个查询字符串参数表示一个整数值:

from urllib.parse import parse_qs

my_values = parse_qs('red=5&blue=0&green=', keep_blank_values=True)
print(repr(my_values))

有些查询字符串参数可能有多个值,有些可能只有一个值,有些可能存在但有空白值,还有一些可能完全没有。
在结果字典上使用get方法会在每种情况下返回不同的值:

print('Red:', my_values.get('red'))
print('Green:', my_values.get('green'))
print('Opacity: ', my_values.get('opacity'))

如果在不提供参数或为空时分配默认值0就好了。我可能会选择使用布尔表达式来实现这一点,因为感觉这种逻辑还不值得使用整个if语句或辅助函数

red = my_values.get('red', [''])[0] or 0
green = my_values.get('greeen', [''])[0] or 0
opacity = my_values.get('opacity', [''])[0] or 0
print(f"Red:      {red!r}")
print(f"Green:    {green!r}")
print(f"Opacity:  {opacity!r}")

如果期望获取的是 int类型,那么代码如下:

red = int(my_values.get('red', [''])[0] or 0)
green = int(my_values.get('greeen', [''])[0] or 0)
opacity = int(my_values.get('opacity', [''])[0] or 0)

现在代码的可读性已经不好了

Python使用if / else条件表达式或ternary表达式使这样的情况更清晰,同时保持代码简短

red_str = my_values.get('red', [''])
red = int(red_str[0]) if red_str[0] else 0

这看上去似乎好了一些。减少了复杂程度,if/else 使得代码更加清晰。一种改进的写法

green_str = my_values.get('green', [''])
if green_str[0]:
    green = int(green_str[0])
else:
    green = 0

如果你需要重复使用这个逻辑——甚至只是两三次,就像在这个例子中一样——那么编写一个辅助函数就是最好的方法:

def get_first_int(values, key, default=0):
    found = values.get(key, [''])
    if found[0]:
        return int(found[0])
    return default

小结

  • Python的语法使编写过于复杂和难以阅读的单行表达式变得容易
  • 将复杂的表达式移到辅助函数中,特别是当您需要重复使用相同的逻辑时
  • 与在表达式中使用布尔运算符or 和 and相比,if / else表达式提供了更具可读性的替代方法。
posted @ 2020-06-08 22:25  码上的生活  阅读(192)  评论(0编辑  收藏  举报