python - 如何将生成器函数转换为python中的迭代器对象?
问题描述
通常生成器函数比迭代器更容易编写,例如考虑这个示例生成器函数
def generator_fn():
x = 0
for y in range(10):
x += y
yield x
有没有一种直接的方法可以将任意生成器函数转换为迭代器对象,即
class IteratorFromGenerator(object):
def __init__(self, generator_fn):
self.generator_fn = generator_fn
def __iter__(self):
# ???
pass
def __next__(self):
# ???
pass
对我来说,这似乎是有利的,但不可能。有利,因为生成器函数通常更容易编写并且需要更少的代码。通常,我开始编写生成器函数,并且在某些时候,我需要一个迭代器对象(例如,何时generator_fn
是 my 的成员,class Foo
我想编写for x in my_foo
而不是for x in my_foo.generator_fn()
. 不可能,因为生成器函数定义了循环过程的执行流程,而迭代器对象只需提供它们的__next__
接口以由未定义的“外部”执行流程请求。
我是对的还是有可能这样做?
当然,除了将所有生成的元素消耗到列表中的琐碎、消耗内存的解决方案之外。
谢谢你的帮助。
解决方案
带有 yield 的函数是一个函数,当被调用时,它会返回一个生成器对象的实例(它是一种特定类型的迭代器)。因此,正如评论中已经提到的,您只需要做:
def generator_fn():
x = 0
for y in range(10):
x += y
yield x
iterator_from_generator_fn = generator_fn()
但是,这样做,你可能会遇到这个问题:在 Python 中重置生成器对象,因为根据定义,你只能迭代生成器一次。
您可能想要的是一个 iterable :一个__iter__
方法返回一个迭代器对象的对象。像这样的东西:
class IterableFromGenerator(object):
def __init__(self, generator_fn):
self.generator_fn = generator_fn
def __iter__(self):
return generator_fn()
iterable_from_generator_fn = IterableFromGenerator(generator_fn)
推荐阅读
- validation - 如何验证 DjangoRestFramework 中的数据?这是从 Views.py 传递的
- php - 如何通过 TYPO3 命令控制器写入文件
- xml - C#在互联网上下载多个xml
- html - 带有不透明黑框的角背景图像
- c++ - 避免别名模板部分特化的最佳实践
- android - 制作片段的rtl设计
- java - 在 Spring MVC 4 中,我让 Quartz Scheduler 一次运行两次
- bash - 重命名后将子目录文件移动到父目录的Shell脚本
- typescript - 嵌套打字稿泛型
- php - PHP - 获取两个动态 UNIX 时间戳之间的所有日期