Python 什么';在iter()中使用产量的优点是什么?
在Python 什么';在iter()中使用产量的优点是什么?,python,yield-keyword,Python,Yield Keyword,在\uuuu iter\uuuu()函数中使用生成器(收益率)有什么好处?在阅读了Python食谱之后,我明白了“如果您希望生成器向用户公开额外的状态,请不要忘记,您可以轻松地 将其作为类实现,将生成器函数代码放入\uuuu iter\uuu()方法中。” 问题: 额外状态在这里意味着什么 使用yield内部\uuu iter\uu()而不是使用单独的yield函数有什么好处 如果要遵循最佳实践,如果没有生成器函数,则必须实现如下内容: In [7]: class IterableContain
\uuuu iter\uuuu()函数中使用生成器(收益率
)有什么好处?在阅读了Python食谱之后,我明白了“如果您希望生成器向用户公开额外的状态,请不要忘记,您可以轻松地
将其作为类实现,将生成器函数代码放入\uuuu iter\uuu()
方法中。”
问题:
额外状态在这里意味着什么
使用yield
内部\uuu iter\uu()
而不是使用单独的yield
函数有什么好处
如果要遵循最佳实践,如果没有生成器函数,则必须实现如下内容:
In [7]: class IterableContainer:
...: def __init__(self, data=(1,2,3,4,5)):
...: self.data = data
...: def __iter__(self):
...: return IterableContainerIterator(self.data)
...:
In [8]: class IterableContainerIterator:
...: def __init__(self, data):
...: self.data = data
...: self._pos = 0
...: def __iter__(self):
...: return self
...: def __next__(self):
...: try:
...: item = self.data[self._pos]
...: except IndexError:
...: raise StopIteration
...: self._pos += 1
...: return item
...:
In [9]: container = IterableContainer()
In [10]: for x in container:
...: print(x)
...:
1
2
3
4
5
当然,上面的例子是人为的,但希望你能理解这一点。对于发电机,这可以是:
In [11]: class IterableContainer:
...: def __init__(self, data=(1,2,3,4,5)):
...: self.data = data
...: def __iter__(self):
...: for x in self.data:
...: yield x
...:
...:
In [12]: list(IterableContainer())
Out[12]: [1, 2, 3, 4, 5]
至于状态,就是-对象可以有状态,比如属性。您可以在运行时操纵该状态。你可以这样做,尽管我认为这是非常不可取的:
In [19]: class IterableContainerIterator:
...: def __init__(self, data):
...: self.data = data
...: self._pos = 0
...: def __iter__(self):
...: return self
...: def __next__(self):
...: try:
...: item = self.data[self._pos]
...: except IndexError:
...: raise StopIteration
...: self._pos += 1
...: return item
...: def rewind(self):
...: self._pos = min(0, self._pos - 1)
...:
In [20]: class IterableContainer:
...: def __init__(self, data=(1,2,3,4,5)):
...: self.data = data
...: def __iter__(self):
...: return IterableContainerIterator(self.data)
...:
In [21]: container = IterableContainer()
In [22]: it = iter(container)
In [23]: next(it)
Out[23]: 1
In [24]: next(it)
Out[24]: 2
In [25]: it.rewind()
In [26]: next(it)
Out[26]: 1
In [27]: next(it)
Out[27]: 2
In [28]: next(it)
Out[28]: 3
In [29]: next(it)
Out[29]: 4
In [30]: next(it)
Out[30]: 5
In [31]: it.rewind()
In [32]: next(it)
Out[32]: 1
导入json
导入URL库
serviceurl=http://www.py4e.com/code3/geojson.py'
尽管如此:
地址=输入(“输入位置:”)
如果len(address)因为nowplayyild
是可编辑的,但您不必编写迭代器类,因为nowplayyied.\uuuuuuuuu iter\uuuuuu
返回一个生成器,它是迭代器。这很方便。你的问题没有提供全部的上下文。您在Python烹饪书中提到的这句话是关于问题的:*您想定义一个生成器函数,但它涉及到您想以某种方式向用户公开的额外状态。这里的额外状态意味着与程序的其他部分相关的其他信息。我也建议在一年前检查此项,但为什么不在IterableContainer
类中只包含\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuucode>?只需将def\uuuuu iter\uuuuuuuuuuuself(self):return self
,并将\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。所有迭代器都是可迭代的,但并非所有可迭代的都是迭代器。理想情况下,您应该将两者分开。例如,迭代器应该是单遍的,但通常情况下,您希望能够在大多数容器上多次迭代。我想我在语义上迷失的地方是,生成器自动提供\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,因此,使用生成器或\uuuuuuuuuuuuuuuuuuuuuuuu
和\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?我认为生成器是一个迭代器,所以选择任何一种方法都是基于您希望如何使用该类。但我确实认为,作为一个生成器,它一次只能执行一次,而作为迭代器实现则允许更多的操作。@pstatix关注点分离是一个加号。生成器对象是迭代器。生成器函数返回生成器对象。因此,由于容器的\uuuu iter\uuuu
返回一个迭代器,因此它现在是一个iterable。但是我们不希望容器成为迭代器并实现\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。我不确定你的意思是“更多的动作”。请考虑给你的代码添加解释,它是如何回答这个问题的。
In [19]: class IterableContainerIterator:
...: def __init__(self, data):
...: self.data = data
...: self._pos = 0
...: def __iter__(self):
...: return self
...: def __next__(self):
...: try:
...: item = self.data[self._pos]
...: except IndexError:
...: raise StopIteration
...: self._pos += 1
...: return item
...: def rewind(self):
...: self._pos = min(0, self._pos - 1)
...:
In [20]: class IterableContainer:
...: def __init__(self, data=(1,2,3,4,5)):
...: self.data = data
...: def __iter__(self):
...: return IterableContainerIterator(self.data)
...:
In [21]: container = IterableContainer()
In [22]: it = iter(container)
In [23]: next(it)
Out[23]: 1
In [24]: next(it)
Out[24]: 2
In [25]: it.rewind()
In [26]: next(it)
Out[26]: 1
In [27]: next(it)
Out[27]: 2
In [28]: next(it)
Out[28]: 3
In [29]: next(it)
Out[29]: 4
In [30]: next(it)
Out[30]: 5
In [31]: it.rewind()
In [32]: next(it)
Out[32]: 1