[英]How do I check if an iterator is actually an iterator container?
我有一个下面的迭代器容器的虚拟示例(真正的读取文件太大而不适合内存):
class DummyIterator:
def __init__(self, max_value):
self.max_value = max_value
def __iter__(self):
for i in range(self.max_value):
yield i
def regular_dummy_iterator(max_value):
for i in range(max_value):
yield i
这允许我多次迭代该值,以便我可以实现这样的事情:
def normalise(data):
total = sum(i for i in data)
for val in data:
yield val / total
# this works when I call next()
normalise(DummyIterator(100))
# this doesn't work when I call next()
normalise(regular_dummy_iterator(100))
如何检查normalize函数,我正在传递一个迭代器容器而不是一个普通的生成器?
首先:没有迭代器容器这样的东西。 你有一个可迭代的 。
迭代生成迭代器。 任何迭代器也是可迭代的,但它自己生成迭代器:
>>> list_iter = iter([])
>>> iter(list_iter) is list_iter
True
如果iter(ob) is ob
test,则没有迭代器。
您可以使用collections.abc
模块测试是否有迭代器( next
一次使用StopIteration
异常消耗)与只有迭代(可能多次迭代)。 这是一个例子:
from collections.abc import Iterable, Iterator
def my_iterator():
yield 1
i = my_iterator()
a = []
isinstance(i, Iterator) # True
isinstance(a, Iterator) # False
是什么让my_iterator()
的Iterator
是既存在__next__
和__iter__
魔术方法(顺便说一句,基本上发生了什么事,当你调用幕后isinstance
在collections.abc
抽象基类是存在的测试某些神奇的方法)。
注意迭代器也是一个Iterable
,就像空列表一样(即两者都有__iter__
魔术方法):
isinstance(i, Iterable) # True
isinstance(a, Iterable) # True
还要注意, 正如Martijn Pieters的回答所指出的 ,当你将泛型iter()
函数应用于两者时,你会得到一个迭代器:
isinstance(iter(my_iterator()), Iterator) # True
isinstance(iter([])), Iterator) # True
[]
和my_iterator()
之间的区别在于iter(my_iterator())
将自身作为迭代器返回 ,而iter([])
每次都会生成一个新的迭代器 。
正如在MP的相同答案中已经提到的,上面的对象不是“迭代器容器”。 它是一个可迭代的对象,即“可迭代的”。 它是否“包含”某些东西并不是真正相关的; contains的概念由抽象基类Container
。 Container
可以是可迭代的,但它不一定必须是可迭代的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.