创建什么对象取决于您循环返回的 Iterable 的 __iter__ 方法。
当迭代一个本身不是迭代器的迭代器时,Python 通常会创建一个迭代器。在 Python2 中,range 返回一个列表,它是一个 Iterable,并且有一个 __iter__ 方法返回一个 Iterator。
>>> from collections import Iterable, Iterator
>>> isinstance(range(300), Iterable)
True
>>> isinstance(range(300), Iterator)
False
>>> isinstance(iter(range(300)), Iterator)
True
for in sequence: do something 语法基本上是执行此操作的简写:
it = iter(some_iterable) # get Iterator from Iterable, if some_iterable is already an Iterator, __iter__ returns self by convention
while True:
try:
next_item = next(it)
# do something with the item
except StopIteration:
break
这是一个演示,其中包含一些打印语句,以阐明使用 for 循环时发生的情况:
class CapitalIterable(object):
'when iterated over, yields capitalized words of string initialized with'
def __init__(self, stri):
self.stri = stri
def __iter__(self):
print('__iter__ has been called')
return CapitalIterator(self.stri)
# instead of returning a custom CapitalIterator, we could also
# return iter(self.stri.title().split())
# because the built in list has an __iter__ method
class CapitalIterator(object):
def __init__(self, stri):
self.items = stri.title().split()
self.index = 0
def next(self): # python3: __next__
print('__next__ has been called')
try:
item = self.items[self.index]
self.index += 1
return item
except IndexError:
raise StopIteration
def __iter__(self):
return self
c = CapitalIterable('The quick brown fox jumps over the lazy dog.')
for x in c:
print(x)
输出:
__iter__ has been called
__next__ has been called
The
__next__ has been called
Quick
__next__ has been called
Brown
__next__ has been called
Fox
__next__ has been called
Jumps
__next__ has been called
Over
__next__ has been called
The
__next__ has been called
Lazy
__next__ has been called
Dog.
__next__ has been called
如您所见,__iter__ 只被调用一次,因此只创建了一个 Iterator 对象。