协程(迭代器,生成器等)

一、 补充知识

isinstance(a,A)
True

以上如果返回值为True则表示a是A的一个子类
在这里插入图片描述
Iterable是一个类,这个类的子类都是可迭代对象
由上图可以知 列表是可迭代对象
问题来了:是否可以通过自己创建的类产生的对象判断ta可以迭代呢?
在这里插入图片描述
发现不可以
如果想让类创建的实例对象用for的话,在类中额外添加方法__iter__
在这里插入图片描述
可行但是依旧不可以拿for来循环‘
因为
在这里插入图片描述
普通列表在for循环中取第一个完成后内部自动跳到第二个,但是自己定义的类没有这个光标
因此得在iter 返回一个对象的引用(这个引用必须包含iter和next方法)才可以进行for循环
在这里插入图片描述
for temp in classmate:
pass

  • 当for循坏是否判断可以运行的时候就是判断classmate是否是一个可迭代对象
  • 如何判断其是否是一个可迭代对象呢?只要classmate中由iter的这个类就算可迭代对象
  • 此时调用对象中iter函数来得到return的返回值,只要返回值中既包含iter和next俩方法,此值就算是迭代器
  • 使用迭代器中的next来进行正常可迭代对象的光标下移
  • 因此每调用一次for循环的temp的时候j就会调用next返回给temp
  • 在这里插入图片描述
    第一行代码iter(classmate)返回迭代器,将迭代器给一个变量
    第二行代码将返回True时证明其就是迭代器
    上两行代码验证其是否是迭代器

协程很简单但是想明白协程得仔细思考
学习迭代器,生成器,yiled(面试 yiled和return有什么区别),greenlet gevent以上

迭代器: 占有极小的内存空间来完成
斐波那契数列:具有后者和等与前两者的和特性的数列

二迭代器的其他用途

不只是for循环可以进行迭代器,类型转换也可以进行迭代器
在这里插入图片描述

元组转换列表,新建列表。重新生成list,通过list()的迭代器一个一个加入新的列表
生成器:特殊的迭代器
创建生成器的一种方法:把列表推导式的中括号换成小括号
在这里插入图片描述
创建生成器的第二种防范:


def creat_num(all_num):
        a,b =0,1
        current_num = 0
        while current_num  < all_num:
                print(a)
                a,b = b,a+b
                current_num +=1

obj = creat_num(10)

上图为斐波那契数列打印结果
在这里插入图片描述
根据上图代码加入了yield,当一个函数中有yeild的时候

  • 说明他是生成器。就把这个函数当做类看待
  • 说明其执行顺序与其他不一样,代码执行到for循环时根据函数从上到下走走到图片中2时即yeild直接打印数值结果,for循环又开始进行第二次循环并不是从头开始而是走到之前yeild暂停的地方继续向下,以后几次循环也只是在while循环中进行

************1.通过next启动生成器启动生成值

在这里插入图片描述
上图可以看到,生成器是特殊的迭代器
因此obj = next(obj)这不是调用函数而是创建了生成器对象
同时拿next’来进行下一步,由结果显示next的值就是yield的值
注意:谁让生成器按照next’返回如果想得到本身函数的返回值则在try中写入ret.value,此中的值value保存了return

def creat_num(all_num):
        a,b =0,1
        current_num = 0
        while current_num  < all_num:
                # print(a)
                yield(a)
                a,b = b,a+b
                current_num +=1



obj = creat_num(10)
while True:
        try:
                ret = next(obj)
                print(ret)
        except Exception as ret:
                print(ret.value)
                break
~
~

**

**********2.通过send来启动生成器去生成值

**
在这里插入图片描述
如上图所示,,yield a 传值给next,next负责打出a之后再回到程序的下一句print(。。。)
但是显然如果用yield左边的赋值语句没有走,所以此时send的内容代表了yield a 传值给ret,则ret打印出来的是哈哈哈哈
生成器特色可以让代码暂停进行并且保存值

三、多任务用途协程------生成器

进程浪费资源,线程比进程轻量级,而协程更加方便快捷

import time

def task_1():
        while True:
                print("-------1----------\n-")
                time.sleep(0.6)
                yield

def task_2():
        while True:
                print("--------2-------")
                time.sleep(0.1)
                yield

def main():
        t1 = task_1()
        t2 = task_2()
        while True:
                next(t1)
                next(t2)

if __name__ == "__main__":
        main()

完成多任务,展示结果如图
在这里插入图片描述

四、yield升级版greenlet

五、gevent协程的并发库

gevent是greenlet的升级版
但不同的是,gevent遇到延时会切任务让其继续下去,不卡死。没有延时时按照正常顺序。
但是time.sleep在gevent不可进行不管用得用gevent.sleep或者使用monkey。parch_all()这个补丁使得正常延迟函数可以运行

发布了41 篇原创文章 · 获赞 0 · 访问量 428

猜你喜欢

转载自blog.csdn.net/weixin_41621686/article/details/104055742