简体   繁体   English

异步协程上的高阶函数

[英]Higher-order function on async coroutine

Let's say I have a function :假设我有一个功能:

def f(x):
    return {"x": x}

I can create a higher-order function that behaves like so :我可以创建一个高阶函数,其行为如下:

def augment(func):
    def augmented_function(x):
         return {**func(x), "metadata": "test"}
    return augmented_function

And then augment(f)(1) will return {"x": 1, "metadata": "test"} .然后augment(f)(1)将返回{"x": 1, "metadata": "test"}

But what if f is an async coroutine, this augment function does not work ( RuntimeWarning: coroutine 'f' was never awaited and TypeError: 'coroutine' object is not a mapping ) - I want the augmented function to be a coroutine that can be awaited :但是如果f是一个异步协程,这个增强函数将不起作用( RuntimeWarning: coroutine 'f' was never awaited and TypeError: 'coroutine' object is not a mapping ) - 我希望增强函数是一个协程,可以等待:

async def f(x):
    return {"x": x}

def augment_async(coro):
   xxx

augment_async(f)(1) # Should return <coroutine object xxx>
await augment_async(f)(1) # Should return {"x": 1, "metadata": "test"}

Does anyone know how to write augment_async in this case?有谁知道在这种情况下如何编写augment_async

Thanks.谢谢。

EDIT : Bonus question.编辑:奖金问题。

How to write augment_async such as await augment_async(f(1)) returns {"x": 1, "metadata": "test"} ?如何写augment_asyncawait augment_async(f(1))返回{"x": 1, "metadata": "test"}

It is sufficient to make the inner function async , so that it can await the wrapped function:使内部函数async就足够了,以便它可以await被包装的函数:

def augment_async(func):
    async def augmented_function(x):
         return {**await func(x), "metadata": "test"}
    return augmented_function

await augment_async(f)(1) # evaluates to {"x": 1, "metadata": "test"}

To “augment” an instantiated coroutine f(1) , a single layer is sufficient:要“增强”实例化的协程f(1) ,单层就足够了:

 async def direct_async(coro):
     return {**await coro, "metadata": "test"}

Note that unlike augment_async , which produces a factory for coroutines, direct_async produces a coroutine directly - its result may be await ed only once.请注意,与生成协程工厂的增加augment_async不同, direct_async直接生成一个协程 - 它的结果可能只被await一次。

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

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