Python - 重载异步方法

Plu*_*rth 9 python oop python-3.x async-await python-requests

我正在为 API 构建一个包装器。目前,它有效。但是,它是同步的,使用 HTTP 调用的请求模块。

我想实现一种异步调用这些方法的方法,而不必使用不同的名称或 lib 版本。我立即想到了重载,但看到 python 中的重载与其他语言有点不同,它看起来不太可能。

本质上,我想构建一个看起来像这样的类(从想法上来说,我知道它在 Python 中不起作用):

class Foo:
    def foo(self):
        # Requests code...
        print("foo sync")

    async def foo(self):
        # aiohttp code...
        print("foo async")
Run Code Online (Sandbox Code Playgroud)

并以这种方式使用它:

f = Foo()
f.foo()
await f.foo()
Run Code Online (Sandbox Code Playgroud)

输出:

>> "foo sync"
>> "foo async"
Run Code Online (Sandbox Code Playgroud)

本质上,在这段代码中,异步函数将完全覆盖前一个函数,这并不是很有帮助。

从一些谷歌搜索来看,这看起来不太可能,但是,Python 总是设法让我感到惊讶。

提前致谢

sto*_*vfl 7

问题:重载异步方法

考虑以下class定义,使用Inheritancewith Overloading!

您有一个class Foo:从中继承的 Base class Foo_async(Foo):
因此,您可以在 insyncasyncmode 中重用大部分实现。
class Foo_async只主要实现的async/await要求。

注意:我正在使用asyncio. 例如:

import asyncio

class Foo():
    def __init__(self):
        self.mode = "sync"

    def __repr__(self):
        return "{}::foo() {}".format(self.__class__.__name__, self.mode)

    def foo(self):
        print("{}".format(self.__repr__()))
        print("\t\tworkload {}".format(1))
        print("\t\tworkload {}".format(2))

class Foo_async(Foo):
    def __init__(self):
        self.mode = "async awaited"

    async def foo(self):
        super().foo()
Run Code Online (Sandbox Code Playgroud)

用法

async def run(foo):
    await foo.foo()

if __name__ == '__main__':
    Foo().foo()

    loop = asyncio.get_event_loop()
    loop.run_until_complete(run(Foo_async()))
    loop.close()
Run Code Online (Sandbox Code Playgroud)

输出

Foo::foo() sync
        workload 1
        workload 2
Foo_async::foo() async awaited
        workload 1
        workload 2
Run Code Online (Sandbox Code Playgroud)

如果您需要更多粒度,请将工作负载拆分def foo(...)为单独的工作负载函数。
现在您可以使用await.

例如:(显示,只更改代码!)

class Foo():
    ...

    def foo(self):
        print("{}".format(self.__repr__()))
        self.workload_1()
        self.workload_2()

    def workload_1(self):
        print("\t\t{} workload {}".format(self.mode, 1))

    def workload_2(self):
        print("\t\t{} workload {}".format(self.mode, 2))

class Foo_async(Foo):
    ...       

    async def foo(self):
        print("{}".format(self.__repr__()))
        await self.workload_1()
        await self.workload_2()

    async def workload_1(self):
        super().workload_1()

    async def workload_2(self):
        super().workload_2()
Run Code Online (Sandbox Code Playgroud)

输出

Foo::foo() sync
        sync workload 1
        sync workload 2
Foo_async::foo() async awaited
        async awaited workload 1
        async awaited workload 2
Run Code Online (Sandbox Code Playgroud)

用 Python 测试:3.5.3