Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 什么';在iter()中使用产量的优点是什么?_Python_Yield Keyword - Fatal编程技术网

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)因为now
    playyild
    是可编辑的,但您不必编写迭代器类,因为now
    playyied.\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