python学习——yield和yield from

一、先来看看yield返回的是什么东东

在这里插入图片描述

  • yield关键字只能在函数中使用,否则会抛出语法异常
    在这里插入图片描述
  • 咱们知道只要在函数中存在yield关键字,那么这个在调用这个函数的时候,其返回值就是一个生成器对象,下图咱们引入from collections.abc import Generator生成器类,判断函数返回的是不是Generator的实例
    在这里插入图片描述
  • 既然知道是Generator,那么要讲Generator就需要再谈谈Iterable可迭代对象和Iterator迭代器
  • 先看继承关系,Iterator是继承自Iterable,而Generator又是继承自Iterator
    在这里插入图片描述
  • 所以说生成器具有可迭代对象和迭代器的所有特性
    在这里插入图片描述

二、可迭代对象

  • 什么是可迭代对象?
  • 可以使用for循环遍历的,那就是可迭代对象。比如for i in range(10): print(i)会打印0-9,其中list str dict tuple等都是可迭代对象
    在这里插入图片描述
  • 其实只要实现了__iter__魔法方法,那么它就是可迭代对象
    在这里插入图片描述
  • 自定义一个可迭代对象,只要实现__iter__方法就行
    在这里插入图片描述

三、什么是迭代器

  • 只要实现__iter____next__方法,就是迭代器
    在这里插入图片描述
  • 迭代器可以使用next()方法获取下一个的值,迭代器也是一个可迭代对象,因为它继承了Iterable,而且他也实现了__iter__方法
  • list str dict tuple等虽然是可迭代对象,但是却不是迭代器
    在这里插入图片描述
  • 他们也不能使用next()获取下一个值
    在这里插入图片描述
  • 自定义迭代器,需要实现__iter____next__方法
    在这里插入图片描述

三、生成器

  • 上面也说过了,生成器需要使用yield关键字,yield from也是返回一个生成器的,放在函数内部即可返回一个生成器
    在这里插入图片描述
  • 也可以使用列表解析,不过需要将方括号[]换成中括号()
    在这里插入图片描述

四、生成器、迭代器、可迭代对象总结

  • 生成器继承迭代器,迭代器继承可迭代对象,可迭代对象继承ABCMeta抽象基类
  • 可迭代对象特性,可以使用for循环遍历,但是不能使用next()方法
  • 迭代器特性,也是可迭代对象,自然可以使用for循环遍历,也可以使用next()方法获取下一个值
  • 生成器特性,既是可迭代对象,也是迭代器,可以使用fornext(),生成器还有send()throw()close()方法

五、再谈yield

  • 咱们现在已经知道yield放在函数内部,会返回一个生成器,可以使用fornext获取下一个值
  • 那么咱们现在来看一下yield后面能跟什么类型的值,而使用for遍历后,打印的值是什么
    在这里插入图片描述
  • 可以看到,yield后面可以跟任意值,而且返回来的和原来一样,即yield后面是什么,返回来的值就是什么
  • 甚至可以yield一个函数
    在这里插入图片描述

六、yield from

  • yield from也是返回一个生成器的
    在这里插入图片描述
  • 看一下yield from后面可以跟什么类型,其实yield from后面只能跟可迭代对象iterable,虽然上图跟的是一个int类型的值,虽然没有报错,但是,咱们用for循环打印一下便知
    在这里插入图片描述
  • 所以yield from后面必须跟一个可迭代类型
  • 咱们看看yield from和yield有什么区别,咱们yield 'abcd',打印的是’abcd’,但是yield from 'abcd'打印的却是a b c d四个分开的字母

在这里插入图片描述
在这里插入图片描述

  • 其实yield from iterable内部帮咱们这样做
    在这里插入图片描述
  • 其实yield from不仅仅只有这么简单,由于还涉及到协程,所以这里就不说那么多

七、总结

  • yieldyield from都只能用于函数内部
  • 都会返回一个生成器对象
  • yieldyield from后面能跟的值有所差别,yield后面能跟几乎所有类型的值,而且使用for循环遍历打印之后的值和后面所跟的值一样,比如yield range(10),打印之后也是range(10);而yield from后面能跟的类型只能是可迭代对象,而且yield from内部会帮我们做一层for遍历,比如yield from range(10),其实内部是做了for i in range(10): yield i这样的一步操作,另外yield from和协程、异步有所挂钩
  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值