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

SymPy相关函数跨会话Pickle加载失败问题排查

问题原因分析

这个错误和SymPy无关,本质是pickle的序列化机制导致的:

  • pickle保存函数时,不会序列化函数的代码逻辑,只记录函数的名称和它所在的模块(比如你在同会话脚本中定义的SymSqr属于__main__模块)。
  • 跨会话加载时,pickle会尝试在当前脚本的__main__模块中查找名为SymSqr的函数,但你的跨会话脚本里没有定义这个函数,因此抛出AttributeError。
解决方案

方案1:将函数放到独立模块(推荐)

把SymSqr函数放到单独的Python模块中,让pickle保存函数的模块路径而非__main__,这样跨会话加载时能正确找到函数定义。

  1. 创建sym_functions.py模块:
from sympy import Symbol

def SymSqr(xExp):
    return xExp * xExp
  1. 修改同会话保存脚本:
import pickle
from sym_functions import SymSqr
from sympy import Symbol

if __name__ == "__main__":
    fileName = 'temp.pickle'
    xSym = Symbol('x')
    
    # 测试原函数
    result = SymSqr(2*xSym)
    print(f'result = {result}')

    # 保存函数
    with open(fileName, 'wb') as outFle:
        pickle.dump(SymSqr, outFle)

    # 同会话加载测试
    with open(fileName, 'rb') as inFile:
        atlFunc = pickle.load(inFile)
    altResult = atlFunc(2 * xSym)
    print(f'altResult = {altResult}')
  1. 跨会话加载脚本:
import pickle
from sym_functions import SymSqr  # 先导入模块中的函数,确保模块存在该定义
from sympy import Symbol

if __name__ == "__main__":
    fileName = 'temp.pickle'
    xSym = Symbol('x')

    # 加载函数
    with open(fileName, 'rb') as inFile:
        loaded_func = pickle.load(inFile)

    # 测试加载后的函数
    result = loaded_func(2 * xSym)
    print(f'result = {result}')

方案2:用dill替代pickle

dill是pickle的扩展,可以直接序列化函数的代码逻辑,不需要依赖模块中的函数定义。

  1. 安装dill:
pip install dill
  1. 修改同会话保存脚本:
import dill
from sympy import Symbol

def SymSqr(xExp):
    return xExp * xExp

if __name__ == "__main__":
    fileName = 'temp.dill'
    xSym = Symbol('x')
    
    result = SymSqr(2*xSym)
    print(f'result = {result}')

    # 用dill保存函数
    with open(fileName, 'wb') as outFle:
        dill.dump(SymSqr, outFle)

    # 同会话加载测试
    with open(fileName, 'rb') as inFile:
        atlFunc = dill.load(inFile)
    altResult = atlFunc(2 * xSym)
    print(f'altResult = {altResult}')
  1. 跨会话加载脚本:
import dill
from sympy import Symbol

if __name__ == "__main__":
    fileName = 'temp.dill'
    xSym = Symbol('x')

    # 用dill加载函数
    with open(fileName, 'rb') as inFile:
        SymSqr = dill.load(inFile)

    # 测试加载后的函数
    result = SymSqr(2 * xSym)
    print(f'result = {result}')

方案3:临时修复(不推荐用于生产)

在跨会话加载脚本中先定义同名的空函数,让pickle能找到名称匹配的对象,之后会覆盖为加载的函数:

import pickle
from sympy import Symbol

# 先定义同名函数,让pickle能找到
def SymSqr(xExp):
    pass

if __name__ == "__main__":
    fileName = 'temp.pickle'
    xSym = Symbol('x')

    with open(fileName, 'rb') as inFile:
        SymSqr = pickle.load(inFile)

    result = SymSqr(2 * xSym)
    print(f'result = {result}')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:13:17