17.3. plural.py, 第 2 阶段
优质
小牛编辑
126浏览
2023-12-01
17.3. plural.py, 第 2 阶段
现在你将增加一个抽象过程。 你从定义一个规则列表开始:如果这样,就做那个,否则判断下一规则。 让我们暂时将程序一部分复杂化以便使另一部分简单化。
例 17.6. plural2.py
import re def match_sxz(noun): return re.search('[sxz]$', noun) def apply_sxz(noun): return re.sub('$', 'es', noun) def match_h(noun): return re.search('[^aeioudgkprt]h$', noun) def apply_h(noun): return re.sub('$', 'es', noun) def match_y(noun): return re.search('[^aeiou]y$', noun) def apply_y(noun): return re.sub('y$', 'ies', noun) def match_default(noun): return 1 def apply_default(noun): return noun + 's' rules = ((match_sxz, apply_sxz), (match_h, apply_h), (match_y, apply_y), (match_default, apply_default) ) def plural(noun): for matchesRule, applyRule in rules: if matchesRule(noun): return applyRule(noun)
这个版本看起来更加复杂 (至少是长了),但做的工作没有变化:试图顺序匹配四种不同规则,并在匹配时应用恰当的正则表达式。 不同之处在于,每个独立的匹配和应用规则都在自己的函数中定义,并且这些函数列于 rules 变量这个元组的元组之中。 | |
使用一个 for 循环,你可以根据 rules 元组一次性进行匹配和应用规则两项工作(一个匹配和一个应用)。 for 循环第一轮中,matchesRule 将使用 match_sxz, applyRule 将使用 apply_sxz; 在第二轮中(假设真走到了这么远), matchesRule 将被赋予 match_h, applyRule 将被赋予 apply_h。 | |
记住 Python 中的一切都是对象,包括函数。rules 包含函数:不是指函数名,而是指函数本身。 当他们被赋予给 for 循环中, matchesRule 和 applyRule 就成了你可以调用的真正函数。 因此,在 for 循环第一轮中,就相当于调用 matches_sxz(noun)。 | |
在 for 循环第一轮中,就相当于调用 apply_sxz(noun),等等。 |
这个抽象过程有些令人迷惑, 试着剖析函数看看实际的等价内容。 这个 for 循环相当于:
例 17.7. 剖析 plural 函数
def plural(noun): if match_sxz(noun): return apply_sxz(noun) if match_h(noun):/ return apply_h(noun) if match_y(noun): return apply_y(noun) if match_default(noun): return apply_default(noun)
这里的好处在于 plural 函数现在被简化了。 它以普通的方法反复使用其它地方定义的规则。 获得一个匹配规则,匹配吗? 调用并应用规则。 规则可以在任意地方以任意方法定义, plural 函数对此并不关心。
现在,添加这个抽象过程值得吗? 嗯... 还不值。 让我们看看如何向函数添加一个新的规则。 啊哈,在先前的范例中,需要向 plural 函数添加一个 if 语句;在这个例子中,需要增加两个函数: match_foo 和 apply_foo,然后更新 rules 列表指定在什么相对位置调用这个新匹配和新规则应用。
这其实不过是步入下一节的一个基石。让我们继续。