python实习总结(yeild,async,azwait和协程)

目录
  • 一、yield使用简析
  • 二、async和await的使用
    • 1.什么是进程、协程、异步?
    • 2.如何处理200W数量的url,把所有的url保存下来?
    • 3.使用async的await和gather
  • 三、协程的理解
  • 总结

一、yield使用简析

yield是一个生成器generator,返回一个interable对象。

该对象具有next()方法,可以通过next()查看接下来的元素是什么。

1.interable对象 ,可以遍历的对象,如: list,str,tuple,dict,file,xrange等。

2.yield的作用是什么?只是循环里面的获取中间变量的一个方法,把想要的变量每次使用yield保存起来直至循环结束,循环结束得到了一个generator对象

3.为什么使用yield?使用yield,一个函数改写成generator,便具有了迭代的能力,比起用类的实例保存状态计算下一个需要迭代的值,代码更加简洁,执行流程十分简单。

4.如何判断yield的类型

def fab(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b      # 使用 yield
        # print b
        a, b = b, a + b
        n = n + 1
for n in fab(5):
    print n

fab不是generator,fab(5)是generator。

好比类的定义和类的实例的区别。

>>>import types
>>> isinstance(fab, types.GeneratorType)
False
>>> isinstance(fab(5), types.GeneratorType)
True

fab 是无法迭代的,而 fab(5) 是可迭代的。

>>>from collections import Iterable
>>> isinstance(fab, Iterable)
False
>>> isinstance(fab(5), Iterable)
True

5.yield在文件读取的应用?

如果字节使用read()读取一个文件,会导致不可预测的内存占用。好的方法是使用yield,固定长度的缓冲区来不断读取文件,生成读文件的迭代的generator。

def read_file(fpath):
    BLOCK_SIZE = 1024
    with open(fpath, 'rb') as f:
        while True:
            block = f.read(BLOCK_SIZE)
            if block:
                yield block
            else:
                return

二、async和await的使用

1.什么是进程、协程、异步?

  • 协程是什么?

一种用户级轻量级的线程,拥有自己的寄存器上下文和栈。

协程切换时候,将寄存器和栈保存在其他地方,当返回的时候,恢复原先保存的寄存器上下文和栈。

  • 为什么使用协程?

主流语言采用多线程并发,线程相关的概念是抢占式多任务,协程相关的协作式多任务。

不管是多进程还是多线程,每次阻塞、切换陷入系统调用。

CPU跑操作系统的调度程序,调度程序决定运行哪一个进程(线程)。

线程非常小心的处理同步问题,而协程完全不存在这个问题。

对于CPU而言,多协程是单线程,CPU不会考虑调度、切换上下文,省去CPU的切换开销。协程好于多线程的原因。

  • 如何使用协程?

多进程+协程下,避开了CPU切换的开销,又能把多个CPU充分利用起来,这种方式对于数据量较大的爬虫还有文件读写之类的效率提升是巨大的。

2.如何处理200W数量的url,把所有的url保存下来?

  • 单进程+单线程
  • 单进程+多线程:开十个线程,速度不能提高十倍。线程的切换是有开销的,无能无限的创建线程。
  • 多进程+多线程:多进程的每个进程占用一个CPU,多线程一定程度上绕过了阻塞时间,所以相比单进程的多线程效率更高。
  • 协程

3.使用async的await和gather

  • await接受一个协程列表,返回done、pending两个列表。done是已经完成的协程,pending是仍在跑的协程。通过.result()获取完成的结果
  • gather以gather(cro1, cro2, cro3, cro4…)的方式接受协程,返回的是一个结合了这么多个任务的协程。

async的使用:https://blog.csdn.net/qq_29785317/article/details/103294235

async def func1(num):
    print('--func1 start--')
    await asyncio.sleep(num)
    print('--func1 done--')
    return 'func1 ok'
async def func2(num):
    print('--func2 start--')
    await asyncio.sleep(num)
    print('--func2 done--')
    return 'func2 ok'
async def main():
    task1 = asyncio.ensure_future(func1(3))
    task2 = asyncio.ensure_future(func2(5))
    tasks = [task1, task2]
    res = await asyncio.gather(*tasks)
    return res
    # done, pending = await asyncio.wait(tasks)
    # for t in done:
    #     print(t.result())
    # print(done)
    # print(pending)
if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    result = loop.run_until_complete(main())
    print(result)
```python
--func1 start--
--func2 start--
--func1 done--
--func2 done--
['func1 ok', 'func2 ok']

三、协程的理解

1.协程的过程

协程中yield是控制流程的方式。

yield同接收器一样,是一个生成器,需要先激活才能使用。

>>> def simple_corotine():
...     print('---->coroutine started')
...     x = yield  #有接收值,所以同生成器一样,需要先激活,使用next
...     print('---->coroutine recvied:',x)
...
>>> my_coro = simple_corotine()
>>> my_coro
<generator object simple_corotine at 0x0000000000A8A518>
>>> next(my_coro)  #先激活生成器,执行到yield val语句  #或者使用send(None)也可以激活生成器
---->coroutine started
>>> my_coro.send(24)  #向其中传入值,x = yield
---->coroutine recvied: 24
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration  #当生成器执行完毕时会报错

2.协程在运行中的四种状态

GEN_CREATE:等待开始执行

GEN_RUNNING:解释器正在执行,这个状态一般看不到

GEN_SUSPENDED:在yield表达式处暂停

GEN_CLOSED:执行结束

>>> def averager():
...     total = 0.0
...     count = 0
...     aver = None
...     while True:
...             term = yield aver
...             total += term
...             count += 1
...             aver = total/count
...
>>> coro_avg = averager()
>>> coro_avg.send(None)
>>> coro_avg.send(10)
10.0
>>> coro_avg.send(20)
15.0
>>> coro_avg.send(30)
20.0
>>> coro_avg.send(40)
25.0

每次循环结束在yield出暂停,直至下一个参数传进来。

3.预激活协程的装饰器(自定义激活的方式)

@装饰器的作用是什么?装饰原有的函数,给原油函数增加一个新的功能和方式。

为什么@可以实现装饰器的功能?函数也是对象,函数可以作为实参传给掐函数。

>>> def coro_active(func):
...     def inner(*args,**kwargs):
...         gen = func(*args,**kwargs)
...         next(gen)   #gen.send(None)
...         return gen
...     return inner
...
>>> @coro_active
... def averager():
...     total = 0.0
...     count = 0
...     aver = None
...     while True:
...             term = yield aver
...             total += term
...             count += 1
...             aver = total/count
...
>>> coro_avg = averager()
>>> coro_avg.send(10) 10.0 >>> coro_avg.send(20) 15.0 >>> coro_avg.send(30) 20.0

4.终止协程和异常处理

当协程的next函数或者send函数发生错误的时候,协程就会终止掉。

需要创建异常捕捉对协程的异常情况进行处理,关闭当前协程。

5.让协程返回值

yield使用方法 ↩︎

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • Python协程asyncio 异步编程笔记分享

    目录 1.事件循环 2.协程和异步编程 2.1 基本使用 2.2 await 2.3 Task对象 1.事件循环 可以理解成为一个死循环,去检查任务列表中的任务,如果可执行就去执行,如果检查不到就是不可执行的,那就忽略掉去执行其他可执行的任务,如果IO结束了(比如说去百度下载图片,下载完了就会变成可执行任务)再去执行下载完成之后的逻辑 #这里的任务是有状态的,比如这个任务已经完成或者正在执行或者正在IO等待 任务列表 = [ 任务1, 任务2, 任务3,... ] while True: 可执行

  • 在Python中如何使用yield

    一.生成器 如果在一个方法内,包含了 yield 关键字,那么这个函数就是一个「生成器」. 生成器其实就是一个特殊的迭代器,它可以像迭代器那样,迭代输出方法内的每个元素. 我们来看一个包含 yield 关键字的方法: # coding: utf8 # 生成器 def gen(n): for i in range(n): yield i g = gen(5) # 创建一个生成器 print(g) # <generator object gen at 0x10bb46f50> print(type

  • Python 协程与 JavaScript 协程的对比

    目录 1.前言 2.什么是协程? 3.混乱的历史 3.1 Python 协程的进化 4.JavaScript 协程的进化 5.Python 协程成熟体 5.1 协程(coroutine) 5.2 任务(Task 对象) 5.3 未来对象(Future) 5.4几种事件循环(event loop) 6.JavaScript 协程成熟体 6.1Promise 继续使用 6.2 async.await语法糖 6.3 js 异步执行的运行机制 6.4 event loop 将任务划分 7.总结与对比 1

  • python中yield的用法详解

    首先我要吐槽一下,看程序的过程中遇见了yield这个关键字,然后百度的时候,发现没有一个能简单的让我懂的,讲起来真TM的都是头头是道,什么参数,什么传递的,还口口声声说自己的教程是最简单的,最浅显易懂的,我就想问没有有考虑过读者的感受. 接下来是正题: 首先,如果你还没有对yield有个初步分认识,那么你先把yield看做"return",这个是直观的,它首先是个return,普通的return是什么意思,就是在程序中返回某个值,返回之后程序就不再往下运行了.看做return之后再把它

  • python实习总结(yeild,async,azwait和协程)

    目录 一.yield使用简析 二.async和await的使用 1.什么是进程.协程.异步? 2.如何处理200W数量的url,把所有的url保存下来? 3.使用async的await和gather 三.协程的理解 总结 一.yield使用简析 yield是一个生成器generator,返回一个interable对象. 该对象具有next()方法,可以通过next()查看接下来的元素是什么. 1.interable对象 ,可以遍历的对象,如: list,str,tuple,dict,file,x

  • 深入浅析python中的多进程、多线程、协程

    进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配.任务的调度. 程序是运行在系统上的具有某种功能的软件,比如说浏览器,音乐播放器等. 每次执行程序的时候,都会完成一定的功能,比如说浏览器帮我们打开网页,为了保证其独立性,就需要一个专门的管理和控制执行程序的数据结构--进程控制块. 进程就是一个程序在一个数据集上的一次动态执行过程. 进程一般由程序.数据集.进程控

  • 简述Python中的进程、线程、协程

    进程.线程和协程之间的关系和区别也困扰我一阵子了,最近有一些心得,写一下. 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度. 线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是的). 协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度. 进程和其他两个的区别还是很明显的. 协程和线程的区别是:协程避免了无意义的调度,由此可以提高性能,但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力. Pyt

  • Python 高级教程之线程进程和协程的代码解析

    目录 进程 进程 5 种基本状态 进程的特点 进程间数据共享 进程池 进程的缺点 线程 线程的定义 使用线程模块的简单示例 代码解析 协程 协程与线程 Python 协程 协程的执行 关闭协程 链接协程以创建管道 总结 进程 进程是指在系统中正在运行的一个应用程序,是 CPU 的最小工作单元. 进程 5 种基本状态 一个进程至少具有 5 种基本状态:初始态.就绪状态.等待(阻塞)状态.执行状态.终止状态. 初始状态:进程刚被创建,由于其他进程正占有CPU资源,所以得不到执行,只能处于初始状态.

  • Python中Async语法协程的实现

    目录 前记 1.传统的Sync语法请求例子 2.异步的请求 3.基于生成器的协程 3.1生成器 3.2用生成器实现协程 前记 在io比较多的场景中, Async语法编写的程序会以更少的时间, 更少的资源来完成相同的任务, 这篇文章则是介绍了Python的Async语法的协程是如何实现的. 1.传统的Sync语法请求例子 还是一样, 在了解Async语法的实现之前, 先从一个Sync的语法例子开始, 现在假设有一个HTTP请求, 这个程序会通过这个请求获取对应的响应内容, 并打印出来, 代码如下:

  • 浅析python协程相关概念

    这篇文章是读者朋友的python协程的学习经验之谈,以下是全部内容: 协程的历史说来话长,要从生成器开始讲起. 如果你看过我之前的文章python奇遇记:迭代器和生成器 ,对生成器的概念应该很了解.生成器节省内存,用的时候才生成结果. # 生成器表达式 a = (x*x for x in range(10)) # next生成值 next(a()) # 输出0 next(a()) # 输出1 next(a()) # 输出4 与生成器产出数据不同的是,协程在产出数据的同时还可以接收数据,具体来说就

  • Python协程方式的实现及意义笔记分享

    目录 协程 1.greenlet实现协程 2.yield 3.asyncio 4.async & awit 2.协程的意义 小结 协程 协程不是计算机提供的,是程序员认为创造 协程也被称为微线程,是一种用户态的上下文切换技术,简而言之,就是通过一个线程实现代码互相切换执行 实现协程的几种方法: 1)greenlet,早期模块 2)yield关键字 3)asyncio装饰器 (python3.4以后引入的) 4)async,await关键字 (python3.5) 推荐 1.greenlet实现协

  • python进阶之协程你了解吗

    目录 协程的定义 协程和线程差异 协程的标准 协程的优点 协程的缺点 python中实现协程的方式 async&await关键字 事件循环 协程函数和协程对象 await Task对象 asyncio.Future对象 futures.Future对象 异步迭代器 什么是异步迭代器? 什么是异步可迭代对象? 异步上下文管理器 uvloop 异步redis 异步MySQL 爬虫 总结 协程的定义 协程(Coroutine),又称微线程,纤程.(协程是一种用户态的轻量级线程) 作用:在执行 A 函数

  • kotlin之协程的理解与使用详解

    前言         为什么在kotlin要使用协程呢,这好比去了重庆不吃火锅一样的道理.协程的概念并不陌生,在python也有提及.任何事务的作用大多是对于所依赖的环境相应而生的,协程对于kotlin这门语言也不例外.协程的优点,总的来说有如下几点:轻量级,占用更少的系统资源: 更高的执行效率: 挂起函数较于实现Runnable或Callable接口更加方便可控: kotlin.coroutine 核心库的支持,让编写异步代码更加简单.当然在一些不适应它的用法下以上优势也会成为劣势. 1.协程

  • kotlin 协程上下文异常处理详解

    目录 引言 一.协程上下文 1.CoroutineContext 2.CorountineScope 3.子协程继承父协程 二.协程的异常传递 1.协程的异常传播 2.不同上下文(没有继承关系)之间协程异常会怎么样? 3.向用户暴露异常 三.协程的异常处理 使用SupervisorJob 异常捕获器CoroutineExceptionHandler Android中全局异常的处理 引言 从前面我们可以大致了解了协程的玩法,如果一个协程中使用子协程,那么该协程会等待子协程执行结束后才真正退出,而达

随机推荐