str 是一个iterable 而不是一个iterator,微妙但重要的区别。请参阅此answer 以获得解释。
您想返回一个带有 __next__ 的对象(或者如果 py2 则只是 next),这是 str 在迭代时返回的内容。
def __iter__(self):
return iter("my string")
str 没有实现__next__
In [139]: s = 'mystring'
In [140]: next(s)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-140-bc0566bea448> in <module>()
----> 1 next(s)
TypeError: 'str' object is not an iterator
然而调用 iter 会返回迭代器,这就是循环调用的:
In [141]: next(iter(s))
Out[141]: 'm'
如果没有 __next__(或 py2 中的 next)方法返回任何内容,您也会遇到同样的问题
您可以使用生成器,它本身具有返回self 的__iter__:
def gen():
yield 'foo'
gg = gen()
gg is gg.__iter__()
True
gg.__next__()
'foo'
class Something:
def __iter__(self):
return gen()
list(Something())
['foo']
或者您自己实现__next__ 的类,例如类似于Ops 帖子中的类(您还必须处理停止循环的StopIteration)
class test:
def __init__(self, somestring):
self.s = iter(somestring)
def __iter__(self):
return self
def __next__(self):
return next(self.s) ## this exhausts the generator and raises StopIteration when done.
In [3]: s = test('foo')
In [4]: for i in s:
...: print(i)
...:
f
o
o