美文网首页
Python异步

Python异步

作者: Recalcitrant | 来源:发表于2019-07-06 18:06 被阅读0次

Python异步之asyncio

一、偏函数

如果需要减少某个函数的参数个数,可以使用 functools.partial() 。
partial() 函数允许给一个或多个参数设置固定的值,以减少接下来被调用时的参数个数。
示例1:

def spam(a, b, c, d):
    print(a, b, c, d)


s1 = partial(spam, 1)
s1(2, 3, 4)
s2 = partial(spam, d=2)
s2(1, 2, 3)
运行结果

示例2:与指定点的欧几里得距离

def distance(p1, p2):
    x1, y1 = p1
    x2, y2 = p2
    return math.hypot(x2-x1, y2-y1)


pt = (7, 4)
points = [(1, 2), (3, 4), (5, 6), (7, 8)]
points.sort(key=partial(distance, pt))
print(points)
运行结果

二、协程函数(异步函数)

1.创建协程函数

使用async关键字可将普通函数变成协程函数,即异步函数。

async def test1():
    print("1")
    print("2")
    
async def test2():
    print("3")
    print("4")

print(test1())
print(test2())
运行结果

除了函数外,类的方法也可以使用async关键词将其变成协程方法:

class test:
    async def run(self):
        pass

2.执行协程函数

async def test1():
    print("1")
    print("2")

async def test2():
    print("3")
    print("4")

a = test1()
b = test2()

try:
    a.send(None)
except StopIteration as e:
    print(e.value)
try:
    b.send(None)
except StopIteration as e:
    print(e.value)
运行结果

3.交叉执行协程函数(await)

async def test1():
    print("1")
    await test2()
    print("2")


async def test2():
    print("3")
    print("4")


a = test1()
try:
    a.send(None)
except StopIteration as e:
    print(e.value)
运行结果

使用async可以定义协程对象,使用await可以针对耗时的操作进行挂起,就像生成器里的yield一样,函数让出控制权。
协程遇到await,事件循环将会挂起该协程,执行别的协程,直到其他的协程也挂起或者执行完毕,再进行下一个协程的执行,协程的目的也是让一些耗时的操作异步化。

注意:await后面跟的必须是一个Awaitable对象,或者实现了相应协议的对象,查看Awaitable抽象类的代码,表明了只要一个类实现了await方法,那么通过它构造出来的实例就是一个Awaitable,并且Coroutine类也继承了Awaitable。

4.自动循环执行协程函数

(1) 事件循环方法

asyncio.get_event_loop()方法
通过asyncio.get_event_loop()方法创建一个事件循环,然后使用run_until_complete()将协程注册到事件循环,并启动事件循环。

import asyncio
async def test1():
    print("1")
    await test2()
    print("2")


async def test2():
    print("3")
    print("4")

loop = asyncio.get_event_loop()
loop.run_until_complete(test1())
运行结果

(2) task任务

由于协程对象不能直接运行,在注册事件循环的时候,其实是run_until_complete方法将协程包装成为了一个任务(task)对象。所谓task对象是Future类的子类,保存了协程运行后的状态,用于未来获取协程的结果。

import asyncio
async def test1():
    print("1")
    await test2()
    print("2")


async def test2():
    print("3")
    print("4")

loop = asyncio.get_event_loop()
task = asyncio.ensure_future(test1())
loop.run_until_complete(task)

print(type(task))
print(task.result())
运行结果

(3) 回调函数

在task执行完毕的时候可以获取执行的结果,回调的最后一个参数是future对象,通过该对象可以获取协程返回值。

import asyncio
async def test1():
    print("1")
    await test2()
    print("2")


async def test2():
    print("3")
    print("4")


def call_back(future):
    print("回调结果:", future.result())


loop = asyncio.get_event_loop()
task = asyncio.ensure_future(test1())
task.add_done_callback(call_back)
loop.run_until_complete(task)
运行结果

相关文章

网友评论

      本文标题:Python异步

      本文链接:https://www.haomeiwen.com/subject/adnphctx.html