目录
序言:
一个对象有实现两个发法:__iter__()、__next__(),则称之为迭代器对象;
一个对象有实现发法__iter__(),则称之为可迭代对象。
内置函数 iter() 只会调用对象的__iter__()方法;
内置函数 next() 只会调用对象的__next__()方法。
Iterable 和 Iterator 都有 __iter__() 方法,异同之处在于 iterable 的__iter__()方法返回一个迭代器,iterator 的__iter__()方法返回本身(也是一个迭代器)。
for 循环本质这里通过三个例子来进行叙述:
例一、p是自定义的迭代器对象
class Person:
def __init__(self):
self.age = 1
def __iter__(self):
print('----------iter')
return self
def __next__(self):
print('----------next')
self.age += 1
if self.age > 6:
raise StopIteration('大于6了')
return self.age
p = Person()
# 通过collections模块判断迭代器、可迭代对象
from collections.abc import Iterable, Iterator
print(isinstance(p, Iterator))
print(isinstance(p, Iterable))
for i in p:
print(i)
此代码执行逻辑:python解释器会先判断 p 是否为可迭代对象,即判断 p 是否存在__iter__()方法,如果存在,则解释器会自动调用 iter() 函数操作 p 即 iter(p),本质上是间接调用 p 的__iter__()方法,返回 self 即迭代器对象本身,并且随后解释器会自动地不断调用 next() 函数操作 self 即 next(self),本质上是间接地不断调用 p 的__next__()方法,返回下一个数据并赋值给 i,同时打印输出。
例二、p是自定义的可迭代对象
class Person:
def __iter__(self):
print('----------iter')
return iter([1,2,3])
p = Person()
from collections.abc import Iterable, Iterator
print(isinstance(p, Iterator))
print(isinstance(p, Iterable))
for i in p:
print(i)
1、
此代码执行逻辑:python解释器会先判断 p 是否为可迭代对象,即判断 p 是否存在__iter__()方法,如果存在,则解释器会自动调用 iter() 函数操作 p 即 iter(p),本质上是间接调用 p 的__iter__()方法,返回 iter([1,2,3]) 即一个迭代器对象,并且随后解释器会自动地不断调用 next() 函数操作 iter([1,2,3]) 即 next(iter([1,2,3])),本质上是间接地不断调用 iter([1,2,3]) 的__next__()方法,返回下一个数据并赋值给 i,同时打印输出;否则,直接抛出 TypeError 错误。【小记:一个对象实现了__iter__()方法就可称之为可迭代对象,不需要考虑该方法返回的是不是迭代器,但是当 for 循环遍历可迭代对象时,该方法必须返回一个迭代器,否则报错。例一也是如此】
2、
此时再考虑一下,如果实例化出 p 对象后,再调用 iter() 函数操作 p 即 iter(p),会怎么样?其实解释器在读取完 lp = iter(p) 后,会间接调用 p 的__iter__()方法,返回 self 即 p 即一个迭代器对象,所以 print(lp is p) 结果为True。
class Person:
def __init__(self):
self.age = 1
def __iter__(self):
print('----------iter')
return self
def __next__(self):
print('----------next')
self.age += 1
if self.age > 6:
raise StopIteration('大于6了')
return self.age
p = Person()
lp = iter(p)
print(lp is p)
例三、p是现成的迭代器对象或可迭代对象
p = iter([1,2,3])
for i in p:
print(i)
p = [1,2,3]
for i in p:
print(i)
代码执行逻辑:对应着例一、例二琢磨。