pythonasync
Ⅰ python什么时候用async await
然而并不会有更多的人因此换到Python 3。他们会说,不就是一点语法糖么,兼容性都保证不了其他再多功能又有什么用。
Ⅱ python里面有类似npm里面的async的库吗
Disclaimer: 以下对比可能有强烈的个人色彩
Node.js > Python 的地方
快:这个快有两方面,第一是V8引擎快,在V8引擎背后操刀的是Lars Bak大神,他创造过高性能SmallTalk引擎和Java Hotspot引擎(现在Java的默认VM),他带领下的V8引擎让Javascript速度达到了一个新的阶段。第二是异步执行,Node.js功能上是一个基于V8引擎的异步网络和IO Library,和Python的Twisted很像,不同的是Node.js的event loop是很底层的深入在语言中的,可以想象成整个文件在执行的时候就在一个很大的event loop里。
npm:npm可以说是用起来最顺手的package management了,npm作为Node.js的官方package management,汇集了整个社区最集中的资源。不像Python经历过easy_install和pip,还有2to3的问题。
Ⅲ 怎么看:Python 3.5 支持 async/await
换汤不换药,但专有关键字也许会比借用 yield from 的语义更明确。
个人不看好 asyncio
系的一点是官方似乎完全没有考虑(或没有引导)大量现有民间库该如何兼容(或迁移),甚至连 3.5 标准库的 smtpd 等都还是 2.x
遗留的实现。asyncio 还只是个裸壳子。(不过这个似乎也是官方推广 Python 3 过程中一贯不负责任的作风,现有的利用 six 库兼容
2.7+ / 3.2+ 的攻略也是民间总结出来的,官方此前推荐是那个完全没有可用性的 lib2to3)
Ⅳ 如何看待 Python 3.5支持Async/Await异步编程
根据Python增强提案(PEP) 第0492号, Python 3.5将通过async和await语法增加对协程的支持。该提案目的是使协程成为Python语言的原生特性,并“建立一种普遍、易用的异步编程思维模型。”
这个新提议中声明一个协程的语法如下:
async def read_data(db):
pass
async是明确将函数声明为协程的关键字,即便没有使用await表达式。这样的函数执行时会返回一个协程对象。
在协程函数内部,可在某个表达式之前使用await关键字来暂停协程的执行,以等待某进程完成:
async def read_data(db):
data = await db.fetch('SELECT ...')
...
由于增强版生成器的存在,Python中其实早已有了协程的形式,例如当yield或yield from声明在Python生成器内部出现,该生成器就会被当作协程。
以下示例展示基于生成器的协程的用法:
>>> def createGenerator():
... mylist = range(3)
... for i in mylist:
... yield i*i
...
>>> mygenerator = createGenerator()
>>> for i in mygenerator:
... print(i)
0
1
4
以上代码中,每当生成器在for循环中被调用,该生成器中的for循环就会返回一个新的值。
关于await用法的更多示例请参见上文提到的PEP #0492.
这个关于协程的新提案想明确地把生成器与协程区分开,这么做有如下好处:
使这两个概念对新开发者来说更易于理解,因为它们二者的语法并不一样;
能消除由于重构时不小心移除了协程中的yield声明而导致的“不明确错误”,这会导致协程变成普通的生成器。
- async def read_data(db):
- data = await db.fetch('SELECT ...')
- if (data...)
- await api.send(data ...')
async/await语法能让程序员以序列方式编写代码,但编译器则会将其当作一系列的协程来处理,从而实现有效的并发。回到我们之前的例子,async/await使我们可以顺序地编写多个await声明语句,就好像每个语句都会阻塞并等待结果,但实际上这并不会导致任何阻塞:
Ⅳ python async=False错误如何修改
你使用的是Python3,而async是Python3中加入的关键字,关键字是不可以作为变量名的。回所以抛出答了一个语法错误(SyntaxError)。
这种情况常见做法是加一个下划线,如:
async_=False
这样它就是一个普通的变量名而不是关键字了。
或者给这个变量换个名字。
PS: 实际上加下划线也就是换名字。。
Ⅵ python 3.6 async 有什么用
Python 3.5中引入了async和await,不建议将这两个名称用作变量名、类名、函数名和模块名。它们将在Python 3.7中正式成为关键字。
Ⅶ 如何用python写一个协程
再写一个任务函数
import asyncio
async def outer():
print('in outer')
print('waiting for result1')
result1 = await phase1()
print('waiting for result2')
result2 = await phase2(result1)
return (result1, result2)
async def phase1():
print('in phase1')
return 'result1'
async def phase2(arg):
print('in phase2')
return 'result2 derived from {}'.format(arg)
event_loop = asyncio.get_event_loop()
try:
return_value = event_loop.run_until_complete(outer())
print('return value: {!r}'.format(return_value))
finally:
event_loop.close()
Ⅷ Python用asyncio模块做协程异步IO爬虫功能,为啥我这两个模块下的代码错误这么多!
随着node.js的盛行,相信大家今年多多少少都听到了异步编程这个概念。Python社区虽然对于异步编程的支持相比其他语言稍显迟缓,但是也在Python3.4中加入了asyncio,在Python3.5上又提供了async/await语法层面的支持,刚正式发布的Python3.6中asynico也已经由临时版改为了稳定版。下面我们就基于Python3.4+来了解一下异步编程的概念以及asyncio的用法。
什么是协程
通常在Python中我们进行并发编程一般都是使用多线程或者多进程来实现的,对于计算型任务由于GIL的存在我们通常使用多进程来实现,而对与IO型任务我们可以通过线程调度来让线程在执行IO任务时让出GIL,从而实现表面上的并发。
其实对于IO型任务我们还有一种选择就是协程,协程是运行在单线程当中的“并发”,协程相比多线程一大优势就是省去了多线程之间的切换开销,获得了更大的运行效率。Python中的asyncio也是基于协程来进行实现的。在进入asyncio之前我们先来了解一下Python中怎么通过生成器进行协程来实现并发。
example1
我们先来看一个简单的例子来了解一下什么是协程(coroutine),对生成器不了解的朋友建议先看一下Stackoverflow上面的这篇高票回答。
Ⅸ 用Python3 的 asyncio 开发的应用有哪些好的部署方案
你要安装 python3.4 ,asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。 例子 https://github.com/michaelliao/learn-python3/blob/master/samples/async/async_hello.py import [email protected] hello(): print(...
Ⅹ 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()041
为了简化,在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()
执行结果如下:
do something before coroutine start123456789101234567891011
这里inner_generator()中执行的代码片段我们实际就可以认为是协程,所以总的来说逻辑图如下:
我们都知道Python由于GIL(Global Interpreter Lock)原因,其线程效率并不高,并且在*nix系统中,创建线程的开销并不比进程小,因此在并发操作时,多线程的效率还是受到了很大制约的。所以后来人们发现通过yield来中断代码片段的执行,同时交出了cpu的使用权,于是协程的概念产生了。在Python3.4正式引入了协程的概念,代码示例如下:
import asyncio# Borrowed from http://curio.readthedocs.org/en/latest/tutorial.html[email protected] 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())
这里会收到这样的报错:
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())27282930
好了现在一个真正的实现了异步编程的小程序终于诞生了。
而目前更牛逼的异步是使用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