Python 为什么iterable对象不是迭代器?
这是我的密码:Python 为什么iterable对象不是迭代器?,python,iterator,Python,Iterator,这是我的密码: 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):
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)
错误:
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:“linehistory”对象不是迭代器
我不知道为什么
linehistory
对象不是迭代器,因为它已经在类中包含了\uuuuuuuuuuuuuuuuuu
方法。迭代器对象需要\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法,但它们还需要实现下一步
:
迭代器对象本身需要支持以下两种方法,这两种方法共同构成迭代器协议:
迭代器
返回迭代器对象本身
迭代器.next()
从容器中返回下一个项目
在Python 3.x中,函数名如下:
迭代器
迭代器。下一个
迭代的概念有很好的文档记录
简而言之,“iterable”是我想要迭代的对象,也称为容器。这可以是一个列表、一个字符串、一个元组或任何其他由多个项组成或可以生成多个项的内容。它具有返回迭代器的\uuuuuuuuuuuuu iter()
“迭代器”是用于一次迭代的对象。它可以看作是一种“光标”。它有next()
(在Python 2中)或\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。由于任何迭代器都是可迭代的(作为自己的迭代器),因此它也有返回自身的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
您可以使用iter(obj)
获得任何iterable的迭代器
在您的示例中,linehistory
(应该编写linehistory
)是可移植的,因为它有一个。用它创建的生成器对象是迭代器(与每个生成器对象一样)
我不知道为什么linehistory对象不是迭代器,因为它已经在类中包含了\uuuuuIter\uuuu
方法
错。见:
迭代器对象本身需要支持以下两种方法,这两种方法共同构成迭代器协议:
iterator.\uuu iter\uuuu()
返回迭代器对象本身。这是允许容器和迭代器与for和in语句一起使用所必需的。此方法对应于Python/CAPI中Python对象类型结构的tp_iter插槽
iterator.\uuuu next\uuuuu()
从容器中返回下一个项目。如果没有其他项,则引发StopIteration异常。此方法对应于Python/CAPI中Python对象类型结构的tp_iternext槽
但是,您可以迭代行
,这是因为您的\uuuu iter\uuu
方法是一个生成器函数,请参阅:
Python的生成器提供了一种实现迭代器协议的方便方法。如果容器对象的\uu iter\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuo()方法作为生成器实现,它将自动返回一个迭代器对象(从技术上讲,是生成器对象),提供\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。有关生成器的更多信息,请参见屈服表达式的文档
其实
所有其他答案都是错误的(除了@glglgl,他写作风格迟钝)。您的生成器函数\uuuu iter\uuuu()
将像这样使用for
循环调用它一样工作
for line in lines:
print(line)
但是因为您使用了next(line)
,所以您必须首先使用iter()
来获取迭代器(我假定它只是调用对象上的uu iter()
正如一样,您还需要定义一个next()
方法(或者对于Python 3来说是\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
方法)。\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu方法缺少:一个方法使对象成为。使用lines=iter(linehistory(f))
你会没事的。另请看:“glglglgl谁的写作风格迟钝”你能详细说明一下吗?@glglglglgl你说了两遍同样的话,下一次它会带来清晰的效果,也就是说,“iterable”是我想迭代的对象
,再次是“iterator”是用于迭代的对象
。接下来介绍next
,并解释这是什么,然后使用生成器再次执行此操作。您基本上假设读者知道什么:迭代、next()和生成器。但主要是你没有提供例子,也没有提到引入的概念。谢谢你的评论。我增加了一些清晰度(希望如此),并提供了一个链接来帮助读者找到“原始”定义。在我的例子中(从您的第一个示例中),line
是一个dict对象。我怎样才能从中提取出关键点(而不是遍历所有内容)?@LShaver如果你在dict
上使用for循环,你只会得到关键点。您还可以在dict
上使用.keys()
,并获得一个keys iterable,其工作方式类似于上例中的行
it = iter(lines)
print(next(it))