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

如何强制SymPy自定义函数每次调用时重新求值

解决SymPy函数缓存导致无法获取numpy数组最新值的问题

SymPy的Function类默认会缓存参数对应的实例,一旦某个参数组合的函数实例被创建(比如U(2,1)),后续调用相同参数时会直接返回缓存结果,不会重新执行eval方法,这就导致修改numpy数组u后,相同参数的U函数无法获取最新值。

解决方案1:禁用函数实例缓存

在自定义的U类中添加_cache = False属性,强制SymPy每次调用函数时都重新创建实例并执行eval方法:

import numpy as np
import sympy as smp

# 初始化u数组(假设steps和cons已定义)
u = np.zeros((steps+1, cons['m']+1), dtype='float')
u[:, :] = np.nan
u[:, 0] = 0
u[0, 1:-1] = 1
u[:, -1] = 0

class U(smp.Function):
    _cache = False  # 禁用实例缓存
    @classmethod
    def eval(cls, i, j):
        global u
        if isinstance(i, smp.Integer) and isinstance(j, smp.Integer):
            val = u[i, j]
            if not np.isnan(val):
                return val

修改后每次调用U(i,j)都会重新检查u数组的最新值,比如:

print(U(2, 1))  # 输出U(2,1)
u[2, 1] = 2
print(U(2, 1))  # 输出2.0

解决方案2:修改数组后手动清除缓存

如果不想完全禁用缓存,可以在修改u数组后,手动清除U类的缓存字典,这样下次调用相同参数时会重新执行eval:

# 修改u数组
u[2, 1] = 2
# 清除U函数的缓存
U._cache.clear()
# 此时调用会重新求值
print(U(2, 1))  # 输出2.0

注意事项

  • 使用global u的方式适合简单场景,复杂场景建议将u封装为类属性或通过闭包传递,避免全局变量带来的副作用。
  • 禁用缓存会略微降低性能(每次调用都要创建新实例),但对于需要实时获取数组最新值的场景,这是必要的权衡。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:50:21