Doc*_*ven 2 python iterator iterable python-3.x
在Python 3中,通过定义__iter__和__next__方法,使类成为可迭代和迭代器是标准过程.但我有问题要绕过这个问题.以此示例创建一个仅生成偶数的迭代器:
class EvenNumbers:
def __init__(self, max_):
self.max_ = max_
def __iter__(self):
self.n = 0
return self
def __next__(self):
if self.n <= self.max:
result = 2 * self.n
self.n += 1
return result
raise StopIteration
instance = EvenNumbers(4)
for entry in instance:
print(entry)
Run Code Online (Sandbox Code Playgroud)
据我所知(如果我错了,请纠正我),当我创建循环时,通过调用itr = iter(instance)内部调用__iter__方法的内容来创建迭代器.这应该返回一个迭代器对象(实例是由于定义__next__,因此我可以返回self).要从中获取元素,next(itr)直到引发异常时才会调用它.
在这里我想问的是现在:是否以及如何能__iter__和__next__分离,从而使后者的功能的内容被定义别的地方?什么时候这可能有用?我知道我必须改变__iter__它以便它返回一个迭代器.
顺便说一句,这个想法来自这个网站(LINK),它没有说明如何实现这个.
听起来你混淆了迭代器和迭代.Iterables有一个__iter__返回迭代器的方法.迭代器有一个__next__方法可以返回它们的下一个值或者引发一个StopIteration.现在在python中,声明迭代器也是可迭代的(但反之亦然),iter(iterator) is iterator因此迭代器itr应该只返回它自己的__iter__方法.
迭代器需要有一个
__iter__()返回迭代器对象本身的方法,因此每个迭代器也是可迭代的,并且可以在大多数接受其他迭代的地方使用
在代码中:
class MyIter:
def __iter__(self):
return self
def __next__(self):
# actual iterator logic
Run Code Online (Sandbox Code Playgroud)
如果你想创建一个自定义迭代器类,最简单的方法是继承collections.abc.Iterator你可以看到__iter__如上定义的定义(它也是它的子类collections.abc.Iterable).那么你需要的只是
class MyIter(collections.abc.Iterator):
def __next__(self):
...
Run Code Online (Sandbox Code Playgroud)
当然有一种更简单的方法来制作迭代器,并且具有生成器功能
def fib():
a = 1
b = 1
yield a
yield b
while True:
b, a = a + b, b
yield b
list(itertools.takewhile(lambda x: x < 100, fib()))
# --> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Run Code Online (Sandbox Code Playgroud)
仅供参考,这是抽象迭代器和迭代的(简化)代码
from abc import ABC, abstractmethod
class Iterable(ABC):
@abstractmethod
def __iter__(self):
'Returns an instance of Iterator'
pass
class Iterator(Iterable, ABC):
@abstractmethod
def __next__(self):
'Return the next item from the iterator. When exhausted, raise StopIteration'
pass
# overloads Iterable.__iter__
def __iter__(self):
return self
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
282 次 |
| 最近记录: |