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

Python协程与iscoroutinefunction问题:同步方法被识别为协程

问题分析与解决方法

为什么iscoroutinefunction会把同步方法识别为协程?

核心问题出在你的timeit装饰器上:

  • 如果装饰器的包装函数用async def定义,不管原方法是不是同步,被装饰后的函数都会被iscoroutinefunction判定为协程函数——这个检测是基于函数的类型标记,而非实际执行逻辑。
  • 要是装饰器内部错误地将原同步方法包装成了协程结构,也会导致这个结果。

无需await调用同步方法的正确方式

第一步:修复timeit装饰器

确保装饰器能正确区分同步/异步函数,输出对应类型的包装函数:

import time
import asyncio
from inspect import iscoroutinefunction

def timeit(func):
    # 处理异步函数
    if iscoroutinefunction(func):
        async def async_wrapper(*args, **kwargs):
            start = time.perf_counter()
            result = await func(*args, **kwargs)
            end = time.perf_counter()
            print(f"{func.__name__} 耗时: {end - start:.6f} 秒")
            return result
        return async_wrapper
    # 处理同步函数
    else:
        def sync_wrapper(*args, **kwargs):
            start = time.perf_counter()
            result = func(*args, **kwargs)
            end = time.perf_counter()
            print(f"{func.__name__} 耗时: {end - start:.6f} 秒")
            return result
        return sync_wrapper

如果你的timeit只需要处理同步方法,直接用纯同步装饰器更简单:

import time

def timeit(func):
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        end = time.perf_counter()
        print(f"{func.__name__} 耗时: {end - start:.6f} 秒")
        return result
    return wrapper

第二步:正常调用同步方法

装饰器修复后,Client.func会被还原为同步方法,直接像普通函数一样调用即可,完全不需要await:

client = Client()
client.func()  # 直接调用,无额外语法

关于RuntimeWarning的补充说明

你看到的警告,本质是被错误装饰后的Client.func变成了协程函数——调用它会返回一个协程对象,但你没有用await或asyncio.run()去执行这个协程,Python因此抛出警告提示协程从未被执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 03:02:40