Effective Python(4): 用辅助函数来取代复杂的

2019-09-27  本文已影响0人  warmsirius

一、举例:从URL中解码查询字符串

1. 使用 urllib.parse 中的 parse_qs 进行解析

使用 urllib.parse 中的 parse_qsURLGET 方法中的键值对进行分割:

>>> from urllib.parse import parse_qs
>>> my_values = parse_qs('red=5&blue=0&green=', keep_blank_values=True)
>>> my_values
{'red': ['5'], 'blue': ['0'], 'green': ['']}

可以看到,每个参数都可以表示一个整数值。

用get方法在my_values字典中查询不同的参数时,就有可能获得不同的值:

>>> 'Red:       ', my_values.get('red')
('Red:       ', ['5'])
>>> 'Blue:      ', my_values.get('blue')
('Blue:      ', ['0'])
>>> 'Green:      ', my_values.get('green')
('Green:      ', [''])

2. 需求

需求1:如果待查询的参数没有出现在字符串中,返回0,如果存在则返回

# For query string   'red=5&blue=0&green='
red = my_values.get('red', [''])[0] or 0
blue = my_values.get('blue', [''])[0] or 0
green = my_values.get('green', [''])[0] or 0

需求2:直接数学方式直接使用参数

# For query string   'red=5&blue=0&green='
red = int(my_values.get('red', [''])[0] or 0)
blue = int(my_values.get('blue', [''])[0] or 0)
green = int(my_values.get('green', [''])[0] or 0)
# For query string   'red=5&blue=0&green='
red = my_values.get('red', [''])[0] or 0
red =  int(red[0]) if red[0] else 0

这种写法比a的方法好一些。

但是,对于不太复杂的情况来说,if/else条件表示式可以令代码变得清晰。但是对于上面这个例子,它的清晰程度还是比不上跨越多行的完整if/else语句。

如果把这个拆分成if/else:

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

可以看出这个函数还是很复杂的,如果需要频繁使用这种逻辑,那就还是应该使用辅助函数

二、 使用 辅助函数 改写功能

将上面的功能抽象成一个通用的辅助函数

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

调用这个辅助函数所使用的代码,要比使用or操作符的长表达式,以及三元表达式更加清晰:

red = get_first_int(my_values, 'red')
blue = get_first_int(my_vaules, 'blue')
green = get_first_int(my_values, 'green')
  • 如果表达式变得比较复杂,那就应该考虑将其拆解成小块,并把这些逻辑移入辅助函数中
  • 不要一味的追求过于紧凑写法,而要追求简单、易读

三、要点

上一篇下一篇

猜你喜欢

热点阅读