美文网首页
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