python-13-迭代器,生成器,协程

列表,字典,字符串,元祖都是可迭代对象(Iterable),这就意味着它们是可以使用 for循环 进行遍历。
检测是否是可迭代对象的方法 isinstance()

    from collections import Iterable
    result=isinstance([1,2],Iterable)
    print('列表',result)
    result=isinstance((1,2),Iterable)
    print('元祖',result)
    result=isinstance({1:'2'},Iterable)
    print('字典',result)
    result=isinstance('sss',Iterable)
    print('字符串型',result)
    result=isinstance(100,Iterable)
    print('int型',result)
    
     列表 True
     元祖 True
     字典 True
     字符串型 True
     intFalse

制作一个迭代器,需要包含 	**iter()函数与next()函数**,如下:

    from collections import Iterable
    class my_iterable():
        def __iter__(self):
            pass
        def __next__(self):
            pass
    ii=my_iterable()
    result=isinstance(ii,Iterable)
    print(result)
 

     True
<font color=#D2691E size=3>当拥有了这两个函数,便被承认为一个可迭代对象

<font face='黑体' color=# size=3>**自定义一个迭代器**

    # 1、MyList类
    class MyList(object):
        # 1)初始化方法
        def __init__(self):
        # 定义实例属性,保存数据
        self.items = []

    # 2)__iter__() 方法,对外提供迭代器
    def __iter__(self):

        # 创建MyListIterator 对象
        mylist_iterator = MyListIterator(self.items)
        # 返回迭代器
        return mylist_iterator

    # 3)addItem() 方法,用来添加数据
    def addItem(self, data):
        # 追加保存数据
        self.items.append(data)
        print(self.items)

    # 2、自定义迭代器类:MyListIterator

    class MyListIterator(object):
        # 1) 初始化方法
        def __init__(self, items):
    
            # 定义实例属性,保存MyList类传递过来的items
            self.items = items
    
            # 记录迭代器迭代的位置
            self.current_index = 0
        # 2)迭代器方法 __iter__()
        def __iter__(self):
            pass
        # 3) 获取下一个元素值的方法 __next__()
        # next(mylist_iterator) 就会调用 __next__() 方法
        def __next__(self):
    
            # 1、 判断当前的下标是否越界
            if self.current_index < len(self.items):
            #     1)根据下标获取下标对应的元素值
                data = self.items[self.current_index]
            #     2)下标位置 +1
                self.current_index += 1
            #     3)返回下标对应的数据
                return data
    
            #  如果越界,直接抛出异常
            else:
    
                # raise 用于主动抛出异常
                # StopIteration 停止迭代
                raise StopIteration
    
    
    if __name__ == '__main__':
        # 1、创建自定义列表对象
        mylist = MyList()
        mylist.addItem("张飞")
        mylist.addItem("关羽")
        mylist.addItem("班长")
        mylist.addItem("xxxxx")
    
        # 遍历
        # 1) iter(mylist) 获取 mylist对象的迭代器  --> MyList --> __iter__()
        # 2)next(迭代器) 获取下一个值
        # 3)捕获异常
        # for value in mylist:
        #     print("name:", value)
    
    
    
        mylist_iterator = iter(mylist)
        # value = next(mylist_iterator)
        # print(value)
        #
        # value = next(mylist_iterator)
        # print(value)

3.生成器

生成器是一种特殊的迭代器,它更加便捷
创建生成器的第一种方法
1 . 列表推导式创建法(将列表推导式外面的 [] 变成())

kk=(aa*2 for aa in range(20))
2 . yeid创建

    def work1():
       yield 10                          # 程序执行到yield语句的时候,程序暂停,返回yield后面表达式的值,在下一次调用的时候,从yield语句暂停的地方继续执行
       yield 100
    kk=work1()
    value=next(kk)
    print(value)

## 4 . 协程
从技术的⻆度来说,“协程就是你可以暂停执⾏的函 数”。如果你把它理解成“就像⽣成器⼀样”,那么你就想对了。

协程存在的意义:对于多线程应⽤,CPU通过切⽚的⽅式来切换线程间的执⾏,线程切换时需要 耗时(保存状态,下次继续)。协程,则只使⽤⼀个线程(单线程),在⼀个线程中规定某个代码块 执⾏顺序
①第一种协程方式

    import time
    def work1():
       while True:               
        print('正在执行work1')
        yield                                        #执行大yield会暂停并保存当前状态,随即去处理work2
        time.sleep(0.5)                              #加时间延迟方便观察
    
    def work2():
       while True:
        print('正在执行work2')
        yield                                        #执行大yield会暂停并保存当前状态,随即去处理work1
        time.sleep(0.5)
    
    if __name__ == '__main__':
        w1 = work1()
        w2 = work2()
        while True:
          next(w1)
          next(w2)

②第二种协程方式

    import time
    from greenlet import  greenlet
    def work1():
        while True:
            print('正在运行work1')
            time.sleep(0.5)
            w2.switch()
    
    def work2():
        while True:
            print('正在执行work2')
            time.sleep(0.5)
            w1.switch()
    
    if __name__ == '__main__':
            w1=greenlet(work1)
            w2=greenlet(work2)
            w1.switch()

③第三种协程方式(常用重要必记)

    import  time
    import gevent                      #gevent 可以自动识别耗时代码然后切换到另一个任务
    from gevent import monkey
    monkey.patch_all()                 # 破解所有未识别的命令
    
    def work1():
        while True:
            print('正在执行work1...')
            time.sleep(0.3)
    
    def work2():
        while True:
            print('正在执行work2...')
            time.sleep(0.3)
    if __name__ == '__main__':
        # 指派任务
        g1=gevent.spawn(work1)                  # gevent.spawn(函数名,参数1,参数2,参数3....)
        g2=gevent.spawn(work2)
    
        g1.join()      # join 阻塞,让主进程等待协程运行。
        g2.join()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值