下面是我的代码:
from collections import deque
class linehistory:
def __init__(self, lines, histlen=3):
self.lines = lines
self.history = deque(maxlen=histlen)
def __iter__(self):
for lineno, line in enumerate(self.lines,1):
self.history.append((lineno, line))
yield line
def clear(self):
self.history.clear()
f = open('somefile.txt')
lines = linehistory(f)
next(lines)
错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'linehistory' object is not an iterator
我不知道为什么linehistory
对象不是迭代器,因为它已经在the
类中包含了__iter__
方法。
6条答案
按热度按时间ig9co6j11#
迭代的概念在Python文档中有详细的说明。
简言之,“iterable”是提供了我想要迭代的项的对象。它要么已经包含了这些项,那么它也被称为容器。它可以是一个列表、一个字符串、一个元组或任何其他由零到多个项组成的对象。但它也可以是一个产生项的对象。例如
itertools
中包含的许多类之一,它有__iter__()
返回一个迭代器。一个“迭代器”是用于一次迭代的对象。它可以被看作是一种“游标”。它有
next()
(在Python 2中)或__next__()
(在Python 3中),它们被反复调用,直到它引发一个StopIteration
异常。由于任何迭代器都是可迭代的(作为它自己的迭代器),它也有__iter__()
,它返回自己。你可以用
iter(obj)
得到任何可迭代对象的迭代器。在你的例子中,
linehistory
(应该写成LineHistory
)是可迭代的,因为它有一个.__iter__()
。用它创建的生成器对象是一个迭代器(和每个生成器对象一样)。neskvpey2#
实际上
for
循环调用生成器函数__iter__()
,它将按原样工作,如下所示但是因为使用了
next(lines)
,所以必须首先使用iter()
来获取迭代器(我假设它只是对对象调用__iter__()),如下所示正如比兹利先生所指出的
uidvcgyl3#
我不知道为什么linehistory对象不是迭代器,因为它已经在类中包含了
__iter__
方法。错误。请参阅迭代器类型:
迭代器对象本身需要支持以下两个方法,这两个方法共同构成了迭代器协议:
iterator.__iter__()
返回迭代器对象本身。这是允许容器和迭代器都能与for和in语句一起使用所必需的。这个方法对应于Python/C API中Python对象类型结构的tp_iter槽。
iterator.__next__()
返回容器中的下一项。如果没有更多项,则引发StopIteration异常。该方法对应于Python/C API中Python对象类型结构的tp_iternext槽。
但是您可以迭代
lines
,这是因为您的__iter__
方法是一个生成器函数,请参阅生成器类型:Python的生成器提供了一种实现迭代器协议的便捷方式。如果一个容器对象的
__iter__()
方法被实现为生成器,它会自动返回一个提供__iter__()
和__next__()
方法的迭代器对象(技术上讲,是一个生成器对象)。关于生成器的更多信息可以在yield表达式的文档中找到。plicqrtu4#
迭代器对象需要一个
__iter__
方法,但它们也需要实现next
:迭代器对象本身需要支持以下两个方法,这两个方法共同构成了迭代器协议:
迭代器.iter()
返回迭代器对象本身。
iterator.next()
从容器中返回下一项。
Python 2.7源代码
在Python 3.x中,这些是函数名:
迭代器.iter()
迭代器.next()
Python 3.x源代码
0s0u357o5#
你的对象它不是迭代器,就像列表它不是迭代器,而是可迭代的,你可以让它成为迭代器,因为迭代器本身就是一个对象。
然后:
假设您有一个列表:
你试着打电话
您将获得:
但是,您可以通过在列表上应用iter()来生成列表的迭代器。
因此,请对您的代码执行以下操作:
somefile.txt(我的文件)的第一行:
现在执行:
您将看到:
看到了吗?它现在有了一个next方法!
11dmarpk6#
Python的“类型错误:'list'对象不是迭代器”。若要解决此错误,请将列表传递给
iter()
函数以获取迭代器,例如my_iterator = iter(my_list)
。下面是错误发生的示例。
我们尝试将列表用作迭代器,但列表不是迭代器(它们是可迭代的)。
要解决这个错误,请将列表传递给iter()函数以获取一个迭代器。
函数的作用是:返回一个迭代器。
一个迭代器对象代表一个数据流。每次我们把迭代器传递给next()函数时,就会返回数据流中的下一项。
当迭代器耗尽时,将引发StopIteration异常。
当你在for循环中使用一个列表时,一个迭代器会自动为你创建。
迭代器需要有一个iter()方法,该方法返回迭代器对象本身。
每个迭代器也是一个可迭代对象,但不是每个可迭代对象都是迭代器。
可迭代对象的例子包括所有的序列类型(list、str、tuple)和一些非序列类型,如dict、file对象和其他定义iter()或getitem()方法的对象。
当一个可迭代对象作为参数传递给iter()函数时,它会返回一个迭代器,但是,通常不需要使用iter()函数,因为for语句会自动为我们做这件事。
当使用for语句或向iter()函数传递可迭代对象时,每次都会创建一个新的迭代器。
另一方面,在迭代器耗尽并显示为空容器之前,只能迭代一次。如果需要检查一个值是否可迭代,请使用try/except语句。
如果传入的值不支持iter()方法或序列协议(getitem()方法),iter()函数将引发TypeError。
如果我们向iter()函数传递一个不可迭代的对象,比如整数,就会运行except代码块。
如果传入的值不支持iter()方法或序列协议(getitem()方法),iter()函数将引发TypeError。
如果我们向iter()函数传递一个不可迭代的对象,比如整数,就会运行except代码块。
参考:https://bobbyhadz.com/blog/python-typeerror-list-object-is-not-an-iterator