python异步都有哪些方式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python异步都有哪些方式相关的知识,希望对你有一定的参考价值。

yield相当于return,他将相应的值返回给调用next()或者send()的调用者,从而交出了CPU使用权,而当调用者再次调用next()或者send()的时候,又会返回到yield中断的地方,如果send有参数,还会将参数返回给yield赋值的变量,如果没有就和next()一样赋值为None。但是这里会遇到一个问题,就是嵌套使用generator时外层的generator需要写大量代码,看如下示例: 
注意以下代码均在Python3.6上运行调试

#!/usr/bin/env python# encoding:utf-8def inner_generator():
i = 0
while True:
i = yield i        if i > 10:            raise StopIterationdef outer_generator():
print("do something before yield")
from_inner = 0
from_outer = 1
g = inner_generator()
g.send(None)    while 1:        try:
from_inner = g.send(from_outer)
from_outer = yield from_inner        except StopIteration:            breakdef main():
g = outer_generator()
g.send(None)
i = 0
while 1:        try:
i = g.send(i + 1)
print(i)        except StopIteration:            breakif __name__ == \'__main__\':
main()1234567891011121314151617181920212223242526272829303132333435363738394041

为了简化,在Python3.3中引入了yield from

yield from

使用yield from有两个好处,

1、可以将main中send的参数一直返回给最里层的generator, 
2、同时我们也不需要再使用while循环和send (), next()来进行迭代。

我们可以将上边的代码修改如下:

def inner_generator():
i = 0
while True:
i = yield i        if i > 10:            raise StopIterationdef outer_generator():
print("do something before coroutine start")    yield from inner_generator()def main():
g = outer_generator()
g.send(None)
i = 0
while 1:        try:
i = g.send(i + 1)
print(i)        except StopIteration:            breakif __name__ == \'__main__\':
main()1234567891011121314151617181920212223242526

执行结果如下:

do something before coroutine start123456789101234567891011

这里inner_generator()中执行的代码片段我们实际就可以认为是协程,所以总的来说逻辑图如下: 

接下来我们就看下究竟协程是啥样子

协程coroutine

协程的概念应该是从进程和线程演变而来的,他们都是独立的执行一段代码,但是不同是线程比进程要轻量级,协程比线程还要轻量级。多线程在同一个进程中执行,而协程通常也是在一个线程当中执行。它们的关系图如下:

我们都知道Python由于GIL(Global Interpreter Lock)原因,其线程效率并不高,并且在*nix系统中,创建线程的开销并不比进程小,因此在并发操作时,多线程的效率还是受到了很大制约的。所以后来人们发现通过yield来中断代码片段的执行,同时交出了cpu的使用权,于是协程的概念产生了。在Python3.4正式引入了协程的概念,代码示例如下:

import asyncio# Borrowed from http://curio.readthedocs.org/en/latest/tutorial.html.@asyncio.coroutinedef countdown(number, n):
while n > 0:
print(\'T-minus\', n, \'()\'.format(number))        yield from asyncio.sleep(1)
n -= 1loop = asyncio.get_event_loop()
tasks = [
asyncio.ensure_future(countdown("A", 2)),
asyncio.ensure_future(countdown("B", 3))]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()12345678910111213141516

示例显示了在Python3.4引入两个重要概念协程和事件循环, 
通过修饰符@asyncio.coroutine定义了一个协程,而通过event loop来执行tasks中所有的协程任务。之后在Python3.5引入了新的async & await语法,从而有了原生协程的概念。

async & await

在Python3.5中,引入了aync&await 语法结构,通过”aync def”可以定义一个协程代码片段,作用类似于Python3.4中的@asyncio.coroutine修饰符,而await则相当于”yield from”。

先来看一段代码,这个是我刚开始使用async&await语法时,写的一段小程序。

#!/usr/bin/env python# encoding:utf-8import asyncioimport requestsimport time


async def wait_download(url):
response = await requets.get(url)
print("get response complete.".format(url))


async def main():
start = time.time()
await asyncio.wait([
wait_download("http://www.163.com"),
wait_download("http://www.mi.com"),
wait_download("http://www.google.com")])
end = time.time()
print("Complete in seconds".format(end - start))


loop = asyncio.get_event_loop()
loop.run_until_complete(main())12345678910111213141516171819202122232425

这里会收到这样的报错:

Task exception was never retrieved
future: <Task finished coro=<wait_download() done, defined at asynctest.py:9> exception=TypeError("object Response can\'t be used in \'await\' expression",)>
Traceback (most recent call last):
File "asynctest.py", line 10, in wait_download
data = await requests.get(url)
TypeError: object Response can\'t be used in \'await\' expression123456

这是由于requests.get()函数返回的Response对象不能用于await表达式,可是如果不能用于await,还怎么样来实现异步呢? 
原来Python的await表达式是类似于”yield from”的东西,但是await会去做参数检查,它要求await表达式中的对象必须是awaitable的,那啥是awaitable呢? awaitable对象必须满足如下条件中其中之一:

1、A native coroutine object returned from a native coroutine function .

原生协程对象

2、A generator-based coroutine object returned from a function decorated with types.coroutine() .

types.coroutine()修饰的基于生成器的协程对象,注意不是Python3.4中asyncio.coroutine

3、An object with an await method returning an iterator.

实现了await method,并在其中返回了iterator的对象

根据这些条件定义,我们可以修改代码如下:

#!/usr/bin/env python# encoding:utf-8import asyncioimport requestsimport time


async def download(url): # 通过async def定义的函数是原生的协程对象
response = requests.get(url)
print(response.text)


async def wait_download(url):
await download(url) # 这里download(url)就是一个原生的协程对象
print("get data complete.".format(url))


async def main():
start = time.time()
await asyncio.wait([
wait_download("http://www.163.com"),
wait_download("http://www.mi.com"),
wait_download("http://www.google.com")])
end = time.time()
print("Complete in seconds".format(end - start))


loop = asyncio.get_event_loop()
loop.run_until_complete(main())123456789101112131415161718192021222324252627282930

好了现在一个真正的实现了异步编程的小程序终于诞生了。 
而目前更牛逼的异步是使用uvloop或者pyuv,这两个最新的Python库都是libuv实现的,可以提供更加高效的event loop。

uvloop和pyuv

pyuv实现了Python2.x和3.x,但是该项目在github上已经许久没有更新了,不知道是否还有人在维护。 
uvloop只实现了3.x, 但是该项目在github上始终活跃。

它们的使用也非常简单,以uvloop为例,只需要添加以下代码就可以了

import asyncioimport uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())123

参考技术A Python异步框架常见的有Twisted、Tornado、Gevent 和 tulip等。

python去掉空格常用方式都有哪些?

处理字符串时经常要定制化去掉无用的空格,python 中要么用存在的常规方法,或者用正则处理。那么,python去掉空格常用方式具体有哪些呢?今天就跟随小编一起来了解下吧!

参考技术A

1.去掉左边空格



string = " * it is blank space test * "



print (string.lstrip())



result:



* it is blank space test *



2.去掉右边空格



string = " * it is blank space test * "



print (string.rstrip())



result:



* it is blank space test *



3.去掉左右两边空格



string = " * it is blank space test * "



print (string.strip())



result:



* it is blank space test *



4.去掉所有空格



有两种方式



eg1:调用字符串的替换方法把空格替换成空



string = " * it is blank space test * "



str_new = string.replace(" ", "")



print str_new



result:



*itisblankspacetest*



eg2:正则匹配把空格替换成空



import re



string = " * it is blank space test * "



str_new = re.sub(r"\\s+", "", string)



print str_new



result:



*itisblankspacetest*



关于python去掉空格常用方式有哪些,环球青藤小编就和大家分享到这里了,学习是永无止境的,学习一项技能更是受益终身,所以,只要肯努力学,什么时候开始都不晚。如果您还想继续了解关于python编程的学习方法及素材等内容,可以点击本站其他文章学习。

以上是关于python异步都有哪些方式的主要内容,如果未能解决你的问题,请参考以下文章

Js延迟加载的方式都有哪些?defer和async的区别是啥?

js中for循环里面有异步请求怎么解决

python高并发web框架都有哪些

python中orm 框架都有哪些

分布式系统的异步处理流程通常都有哪些设计解决方案

《高性能利器》--异步调用有哪些实现方式?