返回介绍

14.5 Sentence 类第4版:惰性实现

发布于 2024-02-05 21:59:47 字数 1154 浏览 0 评论 0 收藏 0

设计 Iterator 接口时考虑到了惰性:next(my_iterator) 一次生成一个元素。懒惰的反义词是急迫,其实,惰性求值(lazy evaluation)和及早求值(eager evaluation)是编程语言理论方面的技术术语。

目前实现的几版 Sentence 类都不具有惰性,因为 __init__ 方法急迫地构建好了文本中的单词列表,然后将其绑定到 self.words 属性上。这样就得处理整个文本,列表使用的内存量可能与文本本身一样多(或许更多,这取决于文本中有多少非单词字符)。如果只需迭代前几个单词,大多数工作都是白费力气。

只要使用的是 Python 3,思索着做某件事有没有懒惰的方式,答案通常都是肯定的。

re.finditer 函数是 re.findall 函数的惰性版本,返回的不是列表,而是一个生成器,按需生成 re.MatchObject 实例。如果有很多匹配,re.finditer 函数能节省大量内存。我们要使用这个函数让第 4 版 Sentence 类变得懒惰,即只在需要时才生成下一个单词。代码如示例 14-7 所示。

示例 14-7 sentence_gen2.py: 在生成器函数中调用 re.finditer 生成器函数,实现 Sentence 类

import re
import reprlib

RE_WORD = re.compile('\w+')


class Sentence:

  def __init__(self, text):
    self.text = text  ➊

  def __repr__(self):
    return 'Sentence(%s)' % reprlib.repr(self.text)

  def __iter__(self):
    for match in RE_WORD.finditer(self.text):  ➋
      yield match.group()  ➌

❶ 不再需要 words 列表。

❷ finditer 函数构建一个迭代器,包含 self.text 中匹配 RE_WORD 的单词,产出 MatchObject 实例。

❸ match.group() 方法从 MatchObject 实例中提取匹配正则表达式的具体文本。

生成器函数已经极大地简化了代码,但是使用生成器表达式甚至能把代码变得更简短。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文