迭代器
迭代器类型的定义
1.当类中定义了__iter__ 和__next__两个方法。
2.iter 方法需要返回对象本身,既:self
3.__next__方法,返回下一个数据,如果没有数据了,需要抛出一个StopIteration的异常
创建 迭代器类型
class IT(object):
def __init__(self):
self.counter = 0
def __iter__(self):
return self
def __next__(self):
self.counter += 1
if self.counter == 3:
raise StopIteration()
return self.counter
#根据实例化创建一个迭代器对象
obj1 = IT()
v1 = next(obj1)
print(v1)
v2 = next(obj1)
print(v2)
v3 = next(obj1)
print(v3)
obj2 = IT()
for item in obj2:
print(item)
迭代器对象支持next取值,如果取值结束自动抛出StopIteration
For循环内部再循环时,先执行 __iter__方法,获取一个迭代器对象,然后不断执行next取值(有异常终止循环)
生成器
创建生成器函数
def func():
yield 1
yield 2
创建生成器对象(内部是根据生成器类generator
创建的对象),生成器的内部也声明了__iter__
和__next__
两个方法
obj1 = func()
v1 = next(obj1)
print(v1)
v2 = next(obj1)
print(v2)
v3 = next(obj1)
print(v3)
obj2 = func()
for item in obj2:
print(item)
如果按照迭代器的规定看,其实生成器类也是一种特殊的迭代器类,
可迭代对象
#如果一个类中有__iter__方法且返回一个迭代器对象,则我们称这个类创建的对象为可迭代对象
class Foo(object):
def __iter__(self):
return 迭代器对象
obj = Foo()
可迭代对象时可以使用for来进行循环,在循环内部其实就是可迭代对象先调用__iter__方法返回一个迭代器对象,然后在使用迭代器对象的next功能逐步取值
for item in obj:
pass
例子
class IT(object):
# 迭代器类
def __init__(self):
self.counter = 0
def __iter__(self):
return self
def __next__(self):
self.counter += 1
if self.counter == 3:
raise StopIteration()
return self.counter
class Foo(object):
# 只包含一个__iter__方法
def __iter__(self):
return IT() # IT() 为迭代器对象
1.obj = Foo() # 实例化的对象为 可迭代对象
2.for item in obj: # 循环可迭代对象时,内部先执行obj.__iter__
并获取迭代器对象:不都安致谢迭代器对象next方法
常用的range函数
v1 = range(10000) # v1 为可迭代对象内部有__iter__方法,无__next__方法
v2 = v1.__iter__() # v2 为迭代器对象,内部有__iter__ __next__方法
v2.__next__()
基于可迭代对象&迭代器实现:自定义range
class IterRange(object):
def __init__(self, num):
self.num = num
self.counter = -1
def __iter__(self):
return self
def __next__(self):
self.counter += 1
if self.counter == self.num:
raise StopIteration
return self.counter
class Xrange(object):
def __init__(self, max_num):
self.max_num = max_num
def __iter__(self):
return IterRange(self.max_num)
obj = Xrange(100)
for item in obj:
print(item)
基于可迭代对象&生成器 实现:自定义range
class Xrange(object):
def __init__(self, max_num):
self.max_num = max_num
def __iter__(self):
counter = 0
while counter < self.max_num:
yield counter
counter += 1
obj = Xrange(100)
for item in obj:
print(item)
判断是否是迭代器的方法
元组、列表、字典等常见的数据类型皆为可迭代对象
from collections.abc import Iterable, Iterator
v11 = list([11, 22, 33, 44])
print(isinstance(v11, Iterator)) # flase,判断是否是迭代器,判断依据是__iter__和__next__