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

为何对functools.partial包装的函数调用inspect.isfunction返回False?

为什么functools.partial包装的普通函数与异步函数在inspect检测中表现不同?

现象重现

你观察到的现象确实存在:用functools.partial包装普通函数后,inspect.isfunction()返回False,但包装异步函数后inspect.iscoroutinefunction()返回True。测试代码及输出如下:

import functools
import inspect

def sin(a, b):
    print(a * b)

async def asin(a, b):
    print(a * b)

sin_partial = functools.partial(sin, 5)
asin_partial = functools.partial(asin, 5)

print(inspect.isfunction(sin))
print(inspect.isfunction(sin_partial))
print('----------')
print(inspect.iscoroutinefunction(asin))
print(inspect.iscoroutinefunction(asin_partial))

输出:

True
False
----------
True
True

核心原因

1. inspect.isfunction()的判断逻辑

inspect.isfunction()仅识别原生Python函数对象(即通过def、lambda定义的function类型对象)。而functools.partial()返回的是functools.partial类的实例,并非原生函数类型,因此isfunction()会返回False。

你可以通过type(sin_partial)验证:输出为<class 'functools.partial'>,而非<class 'function'>。

2. inspect.iscoroutinefunction()的特殊处理

与isfunction()不同,iscoroutinefunction()的判断逻辑会穿透包装对象:

  • 首先检查对象是否实现了协程函数特有的__await__方法;
  • 若对象是包装器(比如partial),则会通过__wrapped__属性获取被包装的原函数,再检查原函数是否为协程函数。

partial包装异步函数时会保留原函数的__wrapped__属性,因此iscoroutinefunction()能检测到内部的异步函数,返回True。

如何判断partial包装的是普通函数

如果你需要判断一个partial对象是否包装了普通函数,可以用以下方式:

# 方式1:检查__wrapped__属性指向的对象是否为函数
print(inspect.isfunction(sin_partial.__wrapped__))  # 输出True

# 方式2:封装为判断函数
def is_partial_wrapped_function(obj):
    return isinstance(obj, functools.partial) and inspect.isfunction(obj.__wrapped__)

print(is_partial_wrapped_function(sin_partial))  # 输出True

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:12:46