这是因为next函数调用了传入对象的next方法。
next(...)
x.next() -> the next value, or raise StopIteration
listiterators 和 generators 都有 next 方法。
>>> iter(range(1)).__class__.next
<slot wrapper 'next' of 'listiterator' objects>
>>> iter(x for x in range(1)).__class__.next
<slot wrapper 'next' of 'generator' objects>
但是list 没有它。这就是它引发该异常的原因。
>>> list.next
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'list' has no attribute 'next'
next 不太关心它传递的对象是否是迭代器。
>>> class Foo():
... def next(self):
... return "foo"
...
>>> foo = Foo()
>>> next(foo)
'foo'
>>> next(foo)
'foo'
但添加next 方法并不一定使其成为集合/序列/可迭代。
>>> class Foo():
... def next(self):
... return "Foo"
>>> [x for x in Foo()]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: iteration over non-sequence
>>> iter(Foo())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: iteration over non-sequence
但是添加__iter__ 方法使其成为一个。
>>> class Foo():
... def next(self):
... return "Foo"
... def __iter__(self): return self
...
>>> [x for x in Foo()]
^CTraceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyboardInterrupt
>>> iter(Foo())
<__main__.Foo instance at 0x7fd77307c488>
next 似乎具有与list 相关的内置智能。
>>> class Foo():
... pass
...
>>> foo = Foo()
>>> next(foo)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: instance has no next() method
>>> next(range(20))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list object is not an iterator