简体   繁体   English

如何编写同步和异步代码的类可实例化形式?

[英]How to write a class instantiable form both synchronous and asyncio code?

I am trying to build a class that's instantiable from both "standard" (ie: non asyncio ) code and for asyncio coroutine. 我正在尝试建立一个可从“标准”(即:non asyncio )代码和asyncio coroutine实例化的类。

Specifically some methods need to spawn subprocess es and wait for completion. 具体来说,某些方法需要产生subprocess es并等待完成。 Difference is that, while subprocess is running I shouldn't block the whole program (other coroutines, if they exist, should be able to run). 不同之处在于,在子进程运行时,我不应该阻塞整个程序(其他协程,如果存在,应该可以运行)。

This boils down to use plain: 归结为使用简单:

from subprocess import run
r = run(arg[0], args)

in "standard" code and: 在“标准”代码中:

from asyncio import create_subprocess_exec
r = await create_subprocess_exec(*args)
t = await r.wait()

problem is I cannot await from standard non- async method even if a loop is running (I can test if loop is running to discriminate, but I don't know how to hook to the running loop, if any). 问题是, 即使循环正在运行,我也无法await标准的非async方法(我可以测试循环是否正在运行以进行区分,但是我不知道如何连接到正在运行的循环(如果有))。

What you want to do is not supported by asyncio, and it might not be possible at all. 您要执行的操作不受asyncio支持,并且可能根本无法执行。 Sync and async functions differ not only in function names, but in fundamental semantics of values and function calls. 同步和异步函数不仅在函数名称上有所不同,而且在值和函数调用的基本语义上也有所不同。

Superficially you could do this: 从表面上看,您可以这样做:

def _run_subprocess_sync(args):
    from subprocess import run
    return run(args[0], args)

async def _run_subprocess_async(args):
    from asyncio import create_subprocess_exec
    r = await create_subprocess_exec(*args)
    return await r.wait()

def run_subprocess(args):
    if asyncio.get_event_loop() is not None and asyncio.get_event_loop().is_running():
        return _run_subprocess_async(args)
    else:
        return _run_subprocess_sync(args)

Note that it's ok that in the async case run_subprocess doesn't await the call to _run_subprocess_async because it will return a coroutine object which its caller (presumably an async def function) will await. 请注意,在异步情况下, run_subprocess不会等待对_run_subprocess_async的调用是_run_subprocess_async因为它将返回一个协程对象,其调用者 (可能是async def函数)将等待该对象。

The problem is that this approach won't get you very far because it will require similar if s at every level of the hierarchy. 问题在于这种方法不会使您走得太远,因为在层次结构的每个级别上都需要相似的if For example, if you have a function that calls run_subprocess and does something with its result, it will similarly have to come in two variants, a sync and an async one, and a switch between the two. 例如,如果您有一个调用run_subprocess并对其结果进行处理的函数,则类似地,它必须具有两个变体,一个是sync和async,另一个是在这两个之间的切换。

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

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