迭代器 iterable
1.定义
- 当类中定义了__iter__和__next__两个方法
- __iter__方法需要返回对象本身,即self
- __next__方法,返回下一个数据,如果没有数据,则需要抛出一个StopIteration异常。
官方文档:docs.python.org/3/library/s…
2.创建迭代器类型
class IteratorObject(object):
def __init__(self):
self.counter = 0
def __iter__(self):
return self
def __next__(self):
self.counter += 1
if self.counter > 3:
raise StopIteration("没有next了")
return self.counter
3.实例化创建迭代器对象
迭代器可以通过obj.__next__()
获取next数据,或者通过python内置函数next(obj)
方法获取效果是一样的,当没有下一个next数据时会抛出异常StopIteration
迭代器可以使用for循环,for循环首先会执行__iter__方法获取返回值,并对返回值一直反复执行next,将next数据作为当前循环值,若无next数据则退出循环不会报错。生成器,可迭代对象使用for循环也是同样的原理
obj1 = IteratorObject() # 创建示例
print(obj1.__next__()) # 访问next
print(next(obj1)) # 简洁的访问方式,效果一致
# 迭代器也能通过循环访问
for item in obj1:
print(item)
try:
# 若超出
print(next(obj1))
except StopIteration as e:
print("出错:", e)
for item in obj1:
print(item)
生成器
1.定义
一个函数只要包含yield那这个函数就是生成器函数,实例化生成器函数得到的对象就是生成器对象,生成器对象内部是根据生成器类Generator创建的,而Generator内部也声明了__iter__和__next__,所以生成器是一种特殊的迭代器。
# 创建生成器函数
def func():
yield 1
yield 2
# 创建生成器对象
obj1 = func()
print(next(obj1))
for i in obj1:
print(i)
try:
print(next(obj1))
except StopIteration as e:
print("StopIteration")
2.生成器的好处
生成器能大大降低内存和提高运行速度,下面代码表示新建函数用来创建储存相同数据的对象create_list方法用list类型来创建对象,creat_generator函数用生成器来创建对象,分别运行观察内存消耗和运行时间。
def create_list():
start_time = time.time()
print(f'list 内存前:{mem.memory_usage()}')
a = [i * 4 for i in range(10000000)]
print(f'list 内存后:{mem.memory_usage()}')
print(f'list 运行时间:{time.time() - start_time}')
def create_generator():
start_time = time.time()
print(f'generator 内存前:{mem.memory_usage()}')
# 生成器推导式 不是列表也不是元组
a = (i * 4 for i in range(10000000))
print(f'generator 内存后:{mem.memory_usage()}')
print(f'generator 运行时间:{time.time() - start_time}')
list 内存前:[18.30859375]
list 内存后:[404.8359375]
list 运行时间:0.8840179443359375
generator 内存前:[18.73046875]
generator 内存后:[18.73046875]
generator 运行时间:0.21883869171142578
对比执行结果可明显看出利用生成器来获取对象内存消耗少,运行时间快。这是因为假如对象里包含的所有元素就是一个苹果,现在需要100个苹果,用列表的方式就是把这100个苹果一起生产出来放到房间里;但用生成器的方式就是制造了一个生产苹果的机器,这个机器能生产100个苹果,你需要一个它就生产一个,所以占用内存少速度快。
可迭代对象
1.定义
如果一个类中有__iter__方法且返回一个迭代器对象,则这个类是可迭代对象类。通过这个类创建的对象为可迭代对象。
class Foo(object):
def __iter__(self):
return 迭代器对象/生成器对象