[英]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.