You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为异步协程编写高阶函数augment_async?附扩展问题

解决异步函数的高阶增强问题

先帮你拆解这个问题,分两步搞定:先实现支持异步函数的基础增强功能,再扩展支持直接增强已调用的协程对象。

1. 基础版:增强异步函数的实现

原augment函数失效的核心原因是:异步函数调用后返回的是协程对象,不是直接的字典结果,直接用**func(x)解包会触发TypeError,同时未被await的协程会抛出RuntimeWarning。

我们只需要把增强后的函数也改成异步的,先等待原异步函数执行完成拿到结果,再合并metadata:

async def augment_async(func):
    async def augmented_function(x):
        # 先await异步函数的结果,拿到真正的字典
        original_result = await func(x)
        return {**original_result, "metadata": "test"}
    return augmented_function

# 测试代码
async def f(x):
    return {"x": x}

# 使用方式
coroutine = augment_async(f)(1)
final_result = await coroutine
print(final_result)  # 输出: {"x": 1, "metadata": "test"}

这样调用augment_async(f)(1)会返回一个协程对象,await之后就能得到包含metadata的完整字典,完全符合你的基础需求。


2. 扩展版:支持增强已调用的协程对象

接下来实现扩展需求:让await augment_async(f(1))也能返回正确结果。这时候需要让augment_async能自动识别输入是异步函数还是已调用后的协程对象,分别处理:

import inspect

async def augment_async(obj):
    # 情况1:传入的是异步函数(async def定义的可调用对象)
    if inspect.iscoroutinefunction(obj):
        async def augmented_function(x):
            original_result = await obj(x)
            return {**original_result, "metadata": "test"}
        return augmented_function
    # 情况2:传入的是已经调用后的协程对象
    elif inspect.iscoroutine(obj):
        original_result = await obj
        return {**original_result, "metadata": "test"}
    # 其他情况抛出明确错误
    else:
        raise TypeError("仅支持异步函数或协程对象作为输入")

# 两种场景测试
async def f(x):
    return {"x": x}

# 场景1:增强函数后调用
result1 = await augment_async(f)(1)
print(result1)  # {"x": 1, "metadata": "test"}

# 场景2:直接增强已调用的协程
result2 = await augment_async(f(1))
print(result2)  # {"x": 1, "metadata": "test"}

这个版本的augment_async会自动判断输入类型:如果是异步函数,就返回增强后的异步函数;如果是协程对象,就直接执行它并添加metadata返回,完美覆盖两种使用场景。

内容的提问来源于stack exchange,提问作者jhoareau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 10:43:15