带有外部状态的生成器函数

问题

你想定义一个生成器函数,但是它会调用某个你想暴露给用户使用的外部状态值。

解法

如果你想让你的生成器暴露外部状态给用户,别忘了你可以简单的将它实现为一个类,然后把生成器函数放到 iter () 方法中过去。比如:

from collections import dequeclass linehistory:def __init__(self, lines, histlen=3):self.lines = linesself.history = deque(maxlen=histlen)def __iter__(self):for lineno, line in enumerate(self.lines, 1):self.history.append((lineno, line))yield linedef clear(self):self.history.clear()

为了使用这个类,你可以将它当做是一个普通的生成器函数。然而,由于可以创建一个实例对象,于是你可以访问内部属性值,比如 history 属性或者是 clear() 方法。代码示例如下:

with open('somefile.txt') as f:lines = linehistory(f)for line in lines:if 'python' in line:for lineno, hline in lines.history:print('{}:{}'.format(lineno, hline), end='')

讨论

关于生成器,很容易掉进函数无所不能的陷阱。如果生成器函数需要跟你的程序其他部分打交道的话 (比如暴露属性值,允许通过方法调用来控制等等),可能会导致你的代码异常的复杂。如果是这种情况的话,可以考虑使用上面介绍的定义类的方式。在__iter__() 方法中定义你的生成器不会改变你任何的算法逻辑。由于它是类的一部分,所以允许你定义各种属性和方法来供用户使用。

一个需要注意的小地方是,如果你在迭代操作时不使用 for 循环语句,那么你得先调用 iter() 函数。比如:

>>> f = open('somefile.txt')
>>> lines = linehistory(f)
>>> next(lines)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: 'linehistory' object is not an iterator>>> # Call iter() first, then start iterating
>>> it = iter(lines)
>>> next(it)
'hello world\n'
>>> next(it)
'this is a test\n'
>>>

《Python Cookbook 3rd》笔记(4.6):带有外部状态的生成器函数相关推荐

  1. 《Python Cookbook 3rd》笔记汇总

    文章目录 一.数据结构 二.字符串和文本 三.数字.日期和时间 四.迭代器与生成器 五.文件与IO 一.数据结构 标题 关键词 1.1:拆分序列后赋值给多个变量 可迭代对象.拆分赋值 1.2:拆分任意 ...

  2. 《Python Cookbook 3rd》笔记(1.4):查找最大或最小的N个元素

    <Python Cookbook 3rd>1.4:查找最大或最小的N个元素 问题 怎样从一个集合中获得最大或者最小的N个元素列表? 解法 heapq 模块有两个函数:nlargest()和 ...

  3. Python Cookbook 3rd Edition Documentation

    Python Cookbook 3rd Edition Documentation 文章目录 第一章:数据结构和算法 1.1 解压序列赋值给多个变量 问题 解决方案 讨论 1.2 解压可迭代对象赋值给 ...

  4. Machine Learning with Python Cookbook 学习笔记 第8章

    Chapter 8. Handling Images 前言 本笔记是针对人工智能典型算法的课程中Machine Learning with Python Cookbook的学习笔记 学习的实战代码都放 ...

  5. Machine Learning with Python Cookbook 学习笔记 第6章

    Chapter 6. Handling Text 本笔记是针对人工智能典型算法的课程中Machine Learning with Python Cookbook的学习笔记 学习的实战代码都放在代码压缩 ...

  6. 《Python cookbook》笔记二

    <Python cookbook>笔记二 第二章 字符串和文本 -使用多个界定符分割字符串- 你需要将一个字符串分割为多个字段,但是分隔符 (还有周围的空格) 并不是固定 的. # str ...

  7. Machine Learning with Python Cookbook 学习笔记 第9章

    Chapter 9. Dimensionality Reduction Using Feature Extraction 前言 本笔记是针对人工智能典型算法的课程中Machine Learning w ...

  8. 《Python Cookbook 3rd》笔记(5.1):读写文本数据

    读写文本数据 问题 你需要读写各种不同编码的文本数据,比如 ASCII,UTF-8 或 UTF-16 编码等. 解法 使用带有 rt 模式的 open() 函数读取文本文件(t表示text文本模式,默 ...

  9. 《Python Cookbook 3rd》笔记(3.4):二、八、十六进制整数

    二.八.十六进制整数 问题 你需要转换或者输出使用二进制,八进制或十六进制表示的整数. 解法 为了将整数转换为二进制.八进制或十六进制的文本串,可以分别使用 bin() , oct() 或 hex() ...

最新文章

  1. 现浇板弹性计算还是塑性计算,板塑性和弹性
  2. word2vec (一) 简介与训练过程概要
  3. 设置tomcat服务为80端口,tomcat虚拟主机,tomcat日志
  4. 个人觉得好的文章链接推荐【转载,侵权立删】
  5. 世界上任何一件事的五个模块
  6. 深度 || 既然C编译器是C语言写的,那么第一个C编译器是怎样来的?
  7. 不学无数——SpringBoot入门VI
  8. 5G 爆发前夕,这些科技巨头们聚在一起“密谋”了些什么?!
  9. eclipse中birt插件使用_eclipse安装birt插件
  10. 07向量的点积、数量积、两向量垂直的条件、投影与投影向量、向量的正交分解、几个不等式、用坐标计算数量积
  11. 用.htaccess禁止某IP访问
  12. origin三图合一_利用Origin将多组拟合图放在一张表中的方法
  13. 不是人人都懂的学习要点
  14. 铜陵学院计算机程序设计大赛,ACM程序设计大赛
  15. 计算机硬盘图标怎么更改,Win7硬盘图标怎么改 win7修改硬盘盘符图标的方法
  16. 2018招商银行暑期实习笔试-编程题
  17. pymysql的mysql补丁_MySQL 的增删改查以及 pymysql 的使用
  18. Android7.0 8.0进程保活与拉活的实现方式
  19. NYOJ171 聪明的kk
  20. ChatGPT玩法大全火了,一键复制就能get同款效果:脱口秀张口就来,还能扮演哈利波特...

热门文章

  1. 安卓工控主板运行时会自动重启_工控主板在工业自动化中的应用
  2. xml与oracle对比,Oracle XML DB和DB2 pure XML在XML文档存储查询性能方面的比较分析
  3. 【转】DICOM医学图像读取涉及到的医学坐标体系
  4. 【转】学习Entity Framework 中的Code First
  5. 第十节:进一步扩展两种安全校验方式
  6. 第十六节: EF的CodeFirst模式通过Fluent API修改默认协定
  7. 由浅到深理解ROS(1)
  8. 【数据库】关系数据库理论学习
  9. 记录今天写的几个正则,数字范围的校验
  10. linux 中将文件设置密码,linux – 如何使用公钥在openssl中加密大文件