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

为何无法将装饰后的函数传入scipy.integrate.ode?

为什么装饰后的函数传入scipy.integrate.ode时,包装函数的*args为空?

将装饰后的微分方程函数传入scipy.integrate.ode后,包装函数被调用时*args是空的,导致原函数因缺少t和y参数报错,具体情况如下:

可正常运行的代码

y0, t0 = 1, 0

def dydt(t, y):
    return y*0.5

r = scipy.integrate.ode(dydt)
r.set_initial_value(y0)
r.integrate(10)
assert r.successful()

无法运行的装饰器版本代码

y0, t0 = 1, 0

def dec_func(func):
    def wrap_func(*args, **kwargs):
        return func(*args, **kwargs)
    return wrap_func

@dec_func
def dydt(t, y):
    return y*0.5

r = scipy.integrate.ode(dydt)
r.set_initial_value(y0)
r.integrate(10)
assert r.successful()

报错信息:TypeError: dydt() missing 2 required positional arguments: 't' and 'y',打印len(args)结果为0。

补充测试(使用functools.wraps仍报错)

from functools import wraps

y0, t0 = 1, 0

def dec_func(func):
    @wraps(func)
    def wrap_func(*args, **kwargs):
        return func(*args, **kwargs)
    return wrap_func

@dec_func
def dydt(t, y):
    return y*0.5

r = scipy.integrate.ode(dydt)
r.set_initial_value(y0)
r.integrate(10)
assert r.successful()

原因分析

scipy.integrate.ode内部会通过读取函数的__code__.co_argcount属性来判断参数数量,进而确定调用时是否传入t和y。

  • 普通函数的__code__.co_argcount会正确返回参数个数(比如示例中的dydt返回2);
  • 装饰后的包装函数定义为*args, **kwargs,其__code__.co_argcount为0,即使使用functools.wraps也仅复制函数名、文档字符串等元数据,不会修改这个参数计数属性;
  • ode看到参数计数为0,就不会传入t和y,直接调用包装函数,最终导致原函数因缺少参数报错。

解决办法

方法1:显式匹配原函数参数签名

直接让包装函数的参数与原函数完全一致,确保co_argcount符合ode的预期:

def dec_func(func):
    def wrap_func(t, y):
        return func(t, y)
    return wrap_func

方法2:动态适配任意参数的函数

如果需要装饰不同参数签名的函数,可以用inspect模块动态生成匹配参数的包装函数:

import inspect

def dec_func(func):
    sig = inspect.signature(func)
    params = list(sig.parameters.keys())
    # 动态生成与原函数参数一致的包装函数
    code = f"def wrap_func({', '.join(params)}): return func({', '.join(params)})"
    local_vars = {'func': func}
    exec(code, globals(), local_vars)
    wrap_func = local_vars['wrap_func']
    # 复制原函数元数据
    wrap_func.__name__ = func.__name__
    wrap_func.__doc__ = func.__doc__
    return wrap_func

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:40:48