python-协程

协程

迭代器

  • 可迭代(Iterable):直接作用于for循环变量
  • 迭代器(Iterator):不但可以作用于for循环,还可以被next调用
  • list是典型的可迭代对象,但不是迭代器
  • 通过isinstance判断是否是迭代器
  • iterable和iteration可以转换
    • 通过iter函数

        #isinstance案例
        #判断某一个变量是否是一个实例
        #判断是否可迭代
        from  collections  import Iterable
        l1 = [1,2,3,4,5]
        print(isinstance(l1,Iterable))
        from collections import Iterator
        print(isinstance(l1,Iterator))
      

生成器

  • generator:一边循环一边计算元素的机制/算法
  • 须要满足三个条件:
    • 每次调用都生产出for循环需要的下一个元素
    • 如果达到最后一个后,爆出StopIteration异常
    • 可以被next函数屌用
  • 如何生成一个生成器
    • 直接使用

    • 如果函数中包含yield,则这个函数叫生成器

    • next调用函数,遇到yield返回

        #生成器案例
        #在函数odd中,yield负责返回
        def  odd():
        	print("step 1")
        	yield 1
        	print("step 2")
        	yield 2
        	print("step 3")
        	yield 3
        #odd()是调用函数生成器
        g  =  odd()
        one  =  next(g)
        print(one)
        two = next(g)
        print(two)
        three  = next(g)
        print(three)
      
      
        #裴波那契数列的生成器写法
        def fib(max):
        	n,a,b = 0,0,1
        	while  n < max:
        	yield b
        	a,b = b, a+b
        	n+= 1
        	#需要注意的是,爆出异常的返回值是return的返回值
        	return 'Done'
        ge = fib(5)
        #生成器的典型用法是在for中使用,比较常用的典型生成器就是range
        for  i  in  ge:
        	print(i)
      

协程

  • 历史历程

    • 3.4引入协程,用yield实现
    • 3.5引入协程语法
    • 实现的协程比较好的包有asyncio, tornado, gevent
  • 定义:协程 是为非抢占式多任务产生子程序的计算机程序组件,协程允许不同入口点在不同位置暂停或开始执行程序”。

  • 从技术角度讲,协程就是一个你可以暂停执行的函数,或者干脆把协程理解成生成器

  • 协程的实现:

    • yield返回
    • send调用
  • 协程的四个状态

    • inspect.getgeneratorstate(…) 函数确定,该函数会返回下述字符串中的一个:
    • GEN_CREATED:等待开始执行
    • GEN_RUNNING:解释器正在执行
    • GEN_SUSPENED:在yield表达式处暂停
    • GEN_CLOSED:执行结束
    • next预激(prime)
    • 代码案例v2
  • 协程终止

    • 协程中未处理的异常会向上冒泡,传给 next 函数或 send 方法的调用方(即触发协程的对象)
    • 止协程的一种方式:发送某个哨符值,让协程退出。内置的 None 和Ellipsis 等常量经常用作哨符值==。
  • yield from

    • 调用协程为了得到返回值,协程必须正常终止
    • 生成器正常终止会发出StopIteration异常,异常对象的vlaue属性保存返回值
    • yield from从内部捕获StopIteration异常
    • 案例v03
    • 委派生成器
      • 包含yield from表达式的生成器函数

      • 委派生成器在yield from表达式出暂停,调用方可以直接把数据发给自生成器

      • 子生成器在把产出的值发给调用放

      • 自生成器在最后,解释器会抛出StopIteration,并且把返回值附加到异常对象上

      • 案例v04

          #协程代码案例1
          def  simple_coroutine():
          print('->start')
          x = yield
          print('->recived',x)
          #主线程
          sc = simple_coroutine()
          print(1111)
          next(sc)#预激
          print(2222)
          sc.send('zhexiao')
        
        
          #案例v2, 协程的状态
          def simple_coroutine(a):
          	print('->start')
          	b = yield a 
          	print('->recived',a,b)
          	c = yield a+b
          	print('->',a,b,c)
          # runc
          sc = simple_coroutine(5)
          aa = next(sc)
          pirnt(aa)
          bb = sc.send(6)
          print(bb)
          cc = sc.send(7)
          print(cc)
        
        
          #案例v03
          def gen():
          	for c in 'AB'
          		yield c
          #list直接用生成器作为参数
          print(list(gen()))
          def  gen_new():
          	yield from 'AB'
          print(list(gen_new)))
        
        
        
        
          #案例v04,委派生成器
          from  collections  import  namedtuple
          ResClass = namedtuple('Res','count average')
          #子生成器
          def averager():
          	total = 0.0
          	count = 0
          	average = None
        
          while  True:
          	term = yield
          	#None是哨兵值
          	if term is None:
          		break
          	total  +=term
          	count +=1
          	average = total / count
          return  ResClass(count, average)
        
          #委派生成器
          def  grounper(storage,key):
          	while True:
          		#获取average()返回值
          		storage[key] = yield from averager()
        
          def client():
          	process_data = {
          		'boy_2' :[39.0,40.8,......],
          		'boy_1':[1.38,1.5,1.32,.......]
          }
          storage = {}
          	for k,v in process_data.items():
          		#获取协程
          		coroutine = grouper(storages,k)
          		#预激协程
          		next(coroutine)
          		#发送数据到协程
          		for dt in v:
          			coroutine.send(None)
          	print(storages)
          #run
          client()
        

asyncio

  • python3.4开始引入标准库当中,内置对异步io的支持
  • asyncio本身是一个消息循环
  • 步骤:
    • 创建消息循环

    • 把协程导入

    • 关闭

        import threading
        import asyncio
        #使用协程
        @asyncio.coroutine
        def  hello():
        	print('Hello world!(%s)'%threading.currentThread())
        	print('Start....(%s)'%threading.currentThread())
        	yield from asyncio.sleep(5)
        	print(‘Done....(%s)'%threading.currentThread())
        	print('Hello again!(%s)'%threading.currentThread())
        #启动消息循环
        loop = asyncio.get_event_loop()
        #定义任务
        tasks = [hello(),hello()]
        #asyncio使用wait等待task执行完毕
        loop.run_until_complete(asyncio.wait(tasks))
        #关闭消息循环
        loop.close()
      

async and await

  • 为了更好地表示异步IO
    • python3.5引入
  • 让协程代码更简洁
  • 使用上,可以简单的进行替换
    • 用async替换@asyncio.coroutine
    • await 替换 yield from

aiohttp

  • asyncio实现单线程的并io,在客户端用处不大
  • 在服务器可以asyncio+coroutine配合,因为http是io操作
  • asyncio实现了tcp,udp,ssl等协议
  • aiohttp是给予asyncio实现的http框架
  • pip install aiohttp安装

concurrent.futures

  • python3新增的库
  • 类似于其他语言的线程池的概念
  • 利用multiprocessing实现真正的并行计算
  • 核心原理:以子进程的形式运行多个python解释器,从而令python程序可以利用多核CPU来提升执行速度。由于子进程与与主解释器相分离,所以她们的全局解释器锁也是相互独立的。每个子进程都能完整的使用一个CPU内核
  • concurrent.futures.Executor
    • threadPoolExecutor
    • ProcessPoolExecutor
    • 执行的时候需要自行选择
  • submit(fn,args,kwargs)
    • fn: 异步执行函数
    • args,kwargs函数

current中的map函数

  • map(fn,*iterables,timeout = None)
    • 跟map函数类似
    • 函数需要异步执行
    • timeout:超时时间
    • map跟submit使用一个就行
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值