Python 进阶

第九章 迭代器和生成器

9.1 Python的迭代协议

  • 类中实现了__iter__方法,生成的对象,就是可迭代对象,可以使用for循环取值。
  • 类中同时实现了__iter__和__next__语法,则生成的对象就是迭代器,可以使用next方法取值。
  • 生成器是迭代器的子类,所以说生成器一定是迭代器,同时生成器中还必须实现send和throw两个抽象方法,从abc模块中,我们可以清晰地看到,Iterable,Iterator和Generator的关系。所以自己去读源码往往是最正确而且有效的方式,网上阅读大量的资料,博客最后还是分不清这三者的关系。与此同时,Python中所有collocation的子类生成的对象都是可迭代对象。迭代器提供了一种惰性方式数据的方式。
Iterable >>service>> __iter__() Iterator >>service>> __iter__() __next__() Generator >>service>> __iter__() __next__() send() throw()
from collections.abc import Iterable, Iterator
a = list([1, 2])
print (isinstance(a, Iterable))
# True

9.2 生成器函数的使用

函数中一旦有了yield关键字,那么调用函数就会返回一个生成器。

def gen_fib(index):
    n,a,b = 0,0,1
    while n<index:
        yield b
        a,b = b, a+b
        n += 1
for data in gen_fib(10):
    print (data)
# 1
# 1
# 2
# 3
# 5
# 8
# 13
# 21
# 34
# 55

9.3 生成器的原理

  • Python函数中调用函数会生成栈帧,由于栈帧保存在堆内存上,所以,栈帧可以独立于调用者存在。而生成器原理类似,在yield的同时,栈帧和next会保存起来,下一次调用时会继续执行,类似于恢复现场。
    下面展示一些 内联代码片
def gen_fib(index):
    n,a,b = 0,0,1
    while n<index:
        yield b
        a,b = b, a+b
        n += 1
import dis
gen = gen_fib(3)
print (dis.dis(gen))
for i in gen:
    print(gen.gi_frame.f_lasti)
    print(gen.gi_frame.f_locals)
#  29           0 LOAD_CONST               1 ((0, 0, 1))
#               2 UNPACK_SEQUENCE          3
#               4 STORE_FAST               1 (n)
#               6 STORE_FAST               2 (a)
#               8 STORE_FAST               3 (b)
#
#  30     >>   10 LOAD_FAST                1 (n)
#              12 LOAD_FAST                0 (index)
#              14 COMPARE_OP               0 (<)
#              16 POP_JUMP_IF_FALSE       48
#
#  31          18 LOAD_FAST                3 (b)
#              20 YIELD_VALUE
#              22 POP_TOP
#
#  32          24 LOAD_FAST                3 (b)
#              26 LOAD_FAST                2 (a)
#              28 LOAD_FAST                3 (b)
#              30 BINARY_ADD
#              32 ROT_TWO
#              34 STORE_FAST               2 (a)
#              36 STORE_FAST               3 (b)
#
#  33          38 LOAD_FAST                1 (n)
#              40 LOAD_CONST               2 (1)
#              42 INPLACE_ADD
#              44 STORE_FAST               1 (n)
#              46 JUMP_ABSOLUTE           10
#         >>   48 LOAD_CONST               0 (None)
#              50 RETURN_VALUE
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值