Effective Python(4): 用辅助函数来取代复杂的
2019-09-27 本文已影响0人
warmsirius
一、举例:从URL中解码查询字符串
1. 使用 urllib.parse
中的 parse_qs
进行解析
使用 urllib.parse
中的 parse_qs
对 URL
的 GET
方法中的键值对进行分割:
>>> 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,如果存在则返回
-
or
方法实现:
# 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:直接数学方式直接使用参数
- a. 原有基础:添加
int
操作
# 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)
- b. 使用
三元操作符
# 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')
- 如果表达式变得比较复杂,那就应该考虑将其拆解成小块,并把这些逻辑移入辅助函数中
- 不要一味的追求过于紧凑写法,而要追求简单、易读
三、要点
- 开发者很容易过渡运用Python的语法特性,从而写出特别复杂并且难以理解的单行表达式
- 请把 复杂的表达式、反复使用的相同逻辑 移入辅助函数之中
- 使用
if/else
表达式,要比用or
、and
这样的Boolean
操作符写成的表达式更加清晰