本文共 1653 字,大约阅读时间需要 5 分钟。
本节书摘来自华章社区《编写高质量Python代码的59个有效方法》一书中的第4条:用辅助函数来取代复杂的表达式,作者[美]布雷特·斯拉特金(Brett Slatkin),更多章节内容可以访问云栖社区“华章社区”公众号查看
第4条:用辅助函数来取代复杂的表达式
Python的语法非常精练,很容易就能用一行表达式来实现许多逻辑。例如,要从URL中解码查询字符串。在下例所举的查询字符串中,每个参数都可以表示一个整数值:查询字符串中的某些参数可能有多个值,某些参数可能只有一个值,某些参数可能是空白(blank)值,还有些参数则没有出现在查询字符串之中。用get方法在my_values字典中查询不同的参数时,就有可能获得不同的返回值。
如果待查询的参数没有出现在字符串中,或当该参数的值为空白时能够返回默认值0,那就更好了。这个逻辑看上去似乎并不值得用完整的if语句或辅助函数来实现,于是,你可能会考虑用Boolean表达式。
由于Python的语法非常精练,所以我们很容易就想到了这种做法。空字符串、空列表及零值,都会评估为False。因此,在下面这个例子中,如果or操作符左侧的子表达式估值为False,那么整个表达式的值就将是or操作符右侧那个子表达式的值。red那一行代码是正确的,因为my_values字典里确实有'red'这个键。该键所对应的值是个列表,列表中只有一个元素,也就是字符串'5'。这个字符串会自动估值为True,所以,or表达式第一部分的值就会赋给red。
green那一行代码也是正确的,因为get方法从my_values字典中获取的值是个列表,该列表只有一个元素,这个元素是个空字符串。由于空字符串会自动估值为False,所以整个or表达式的值就成了0。opacity那一行代码也没有错。my_values字典里面没有名为'opacity'的键,而当字典中没有待查询的键时,get方法会返回第二个参数的值,所以,在本例中,get方法就会返回仅包含一个元素的列表,那个元素是个空字符串。当字典里没有待查询的'opacity'键时,这行代码的执行效果与green那行代码相同。这样的长表达式虽然语法正确,但却很难阅读,而且有时也未必完全符合要求。由于我们想在数学表达式中使用这些参数值,所以还要确保每个参数的值都是整数。为了实现这一点,我们需要把每个长表达式都包裹在内置的int函数中,以便把字符串解析为整数。这种写法读起来很困难,而且看上去很乱。这样的代码不容易理解,初次拿到这种代码的人,可能先要花些功夫把表达式拆解开,然后才能看明白它的作用。即使想把代码写得简省一些,也没有必要将全部内容都挤在一行里面。
Python 2.5添加了if/else条件表达式(又称三元操作符),使我们可以把上述逻辑写得清晰一些,同时还能保持代码简洁。这种写法比原来好了一些。对于不太复杂的情况来说,if/else条件表达式可以令代码变得清晰。但对于上面这个例子来说,它的清晰程度还是比不上跨越多行的完整if/else语句。如果把上述逻辑全都改成下面这种形式,那我们能就感觉到:刚才那种紧缩的写法其实挺复杂的。
现在应该把它总结成辅助函数了,如果需要频繁使用这种逻辑,那就更应该这样做。
调用这个辅助函数时所使用的代码,要比使用or操作符的长表达式版本,以及使用if/else表达式的两行版本更加清晰。
表达式如果变得比较复杂,那就应该考虑将其拆解成小块,并把这些逻辑移入辅助函数中。这会令代码更加易读,它比原来那种密集的写法更好。编写Python程序时,不要一味追求过于紧凑的写法,那样会写出非常复杂的表达式。
要点开发者很容易过度运用Python的语法特性,从而写出那种特别复杂并且难以理解的单行表达式。请把复杂的表达式移入辅助函数之中,如果要反复使用相同的逻辑,那就更应该这么做。使用if/else表达式,要比用or或and这样的Boolean操作符写成的表达式更加清晰。转载地址:http://ulncx.baihongyu.com/