Python的字符串是不可变的,所以非常适合函数式编程。Python的string
模块所含的方法都会创建新的字符串作为结果,这些方法都是没有副作用的纯函数。
字符串方法采用后缀写法,而大多数普通函数采用前缀写法,这导致字符串操作和普通函数运算混合在一起时,代码不易读。例如在表达式len(variable.title())
中,title()
采用后缀写法,而len()
函数采用前缀写法。
从网页上爬取数据时,经常会用到清洗函数,对原始字符串执行一系列转换,去掉其中的标点符号,最后返回一个数值对象供其他函数使用,这时前缀写法和后缀写法就会混合在一起。
如下所示:
from decimal import *
from typing import Text, Optional
def clean_decimal(text: Text) -> Optional[Text]:
if text is None: return None
return Decimal(
text.replace("", "$").replace(",", ""))
这个函数对原始字符串进行了两次替换,分别移除其中的$
和逗号,替换结果作为Decimal
类构造函数的参数,返回相应的数值对象。如果输入值是None
,则返回原值,所以使用了类型标示Optional
。
为了使语法更统一,可以自定义前缀式的字符串替换函数,如下所示:
def replace(str: Text, a: Text, b: Text) -> Text:
return str.replace(a, b)
现在可以使用统一的前缀式写法了:Decimal(replace(replace(text, "$", ""), ",", ""))
。对比原来的前缀-后缀混合写法,如此修改后,一致性似乎没有明显提升,这是一个一致性应用欠妥的例子。
更好的做法是重新定义一个语义清晰的前缀式函数来剔除字符串中的标点符号,如下所示:
def remove(str: Text, chars: Text) -> Text:
if chars:
return remove(
str.replace(chars[0], ""),
chars[1:]
)
return str
该函数递归地剔除chars
变量中的每个字符,因此可以把原来分别剔除$
和逗号的函数改写成更清晰的形式:Decimal(remove(text, "$,"))
。