繁体   English   中英

如何泛化可能是异步,龙卷风协程或正常的函数调用?

[英]How to generalize a function call which may be async, tornado coroutine, or normal?

我有一个具有多个配置库的应用程序:

  • Python2.7本机
  • Python2.7龙卷风
  • Python3.5异步

目前,我的代码几乎对所有这三个都完全相同,但是在调用每个函数调用的方式上却有微小的差异。 这意味着我有大量的代码重复,因为在许多地方都有类似以下的内容:

#Python2.7native.py
def main(client):
   client.foo(args)
   client.bar(args)

#Python2.7tornado.py
@gen.coroutine
def main(client):
    yield client.foo(args)
    yield client.bar(args)

#Python3.5asyncio.py
async def main(client):
    await client.foo(args)
    await client.bar(args)

其中client是特定于语言的实现,分别支持本机python,asyncio和Tornado。 API方法调用是相同的。

我希望能够以某种方式将其概括为可以包含在共享文件中的单个方法,该方法可以适当地调用各种方法

我曾考虑过在一个单独的文件中定义方法,并使用getattr正确调用测试,但这似乎很混乱。

有什么好方法吗?

您不能在一个函数中完成所有这些操作client.foo()应该如何知道是从“常规”同步应用程序中调用它,还是其调用者将使用yieldawait 但是,只要您愿意将Tornado作为依赖项,就可以避免将所有代码重复三次。

在一个模块client_async.py ,使用Tornado的@gen.coroutine实现您的功能:

@gen.coroutine
def foo(args):
    yield something()
    yield something_else()
    raise gen.Return(another_thing())

在另一个client_sync.py ,将来自client_async.py每个函数包装在IOLoop.run_sync() ,以实现线程本地的IOLoop,如下所示:

import client_async
import threading
import tornado.ioloop

class _LocalIOLoop(threading.local):
    def __init__(self):
        self.value = tornado.ioloop.IOLoop()
local_ioloop = _LocalIOLoop()

def foo(args):
    return local_ioloop.value.run_sync(lambda: foo_async.my_func(args))

现在,您可以在所有三个环境中使用此代码。 从正常的同步代码:

import client_sync

def main():
    x = client_sync.foo(args)

从龙卷风@gen.coroutine

import client_async

@gen.coroutine
def main():
    x = yield client_async.foo(args)

async defasyncio (请注意,这两个不是同义词-可以在不使用asyncio情况下将asyncioasync def一起使用):

# one-time initialization for Tornado/asyncio integration
import tornado.platform.asyncio
tornado.platform.asyncio.AsyncIOMainLoop().install()

import client_async

async def main():
    x = await client_async.foo(args)

使用@gen.coroutineyield :这将在所有Python版本中工作。 gen.coroutine装饰的功能比本地协程要慢一些,但是可以在所有相同的情况下使用。

对于同步情况,请使用run_sync

result = IOLoop.current().run_sync(main)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM