Python 用lambda序列化cython类时出现pickle错误
我使用pickle和dill来遵循lambda函数,并且工作正常:Python 用lambda序列化cython类时出现pickle错误,python,lambda,cython,pickle,dill,Python,Lambda,Cython,Pickle,Dill,我使用pickle和dill来遵循lambda函数,并且工作正常: import dill import pickle f = lambda x,y: x+y s = pickle.dumps(f) 甚至在课堂上使用,例如: 文件 foo.py 文件 test.py 但是,当使用cython以.pyx(foo.pyx)格式生成相同的文件时,无法使用dill、pickle或cpickle序列化,出现以下错误: 回溯(最近一次呼叫最后一次): 文件“/home/amin/anaconda2/e
import dill
import pickle
f = lambda x,y: x+y
s = pickle.dumps(f)
甚至在课堂上使用,例如:
文件
foo.py
文件
test.py
但是,当使用cython以.pyx(foo.pyx)格式生成相同的文件时,无法使用dill、pickle或cpickle序列化,出现以下错误:
回溯(最近一次呼叫最后一次):
文件“/home/amin/anaconda2/envs/rllab2/lib/python2.7/site-packages/IPython/core/interactiveshell.py”,第2878行,运行代码
exec(代码对象、self.user\u全局、self.user\n)
文件“”,第1行,在
a=酸洗.倾倒(c)
文件“/home/amin/anaconda2/envs/rllab2/lib/python2.7/pickle.py”,第1380行,转储
Pickler(文件,协议).dump(obj)
文件“/home/amin/anaconda2/envs/rllab2/lib/python2.7/pickle.py”,第224行,在转储文件中
自我保存(obj)
文件“/home/amin/anaconda2/envs/rllab2/lib/python2.7/pickle.py”,第331行,保存
自我保存(obj=obj,*rv)
文件“/home/amin/anaconda2/envs/rllab2/lib/python2.7/pickle.py”,第425行,保存
保存(状态)
文件“/home/amin/anaconda2/envs/rllab2/lib/python2.7/pickle.py”,第286行,保存
f(self,obj)#用显式self调用未绑定方法
文件“/home/amin/anaconda2/envs/rllab2/lib/python2.7/site packages/dill/_dill.py”,第912行,保存模块目录
StockPickler.保存目录(pickler,obj)
文件“/home/amin/anaconda2/envs/rllab2/lib/python2.7/pickle.py”,第655行,保存目录
self.\u batch\u setitems(obj.iteritems())
文件“/home/amin/anaconda2/envs/rllab2/lib/python2.7/pickle.py”,第669行,在批处理设置项中
保存(v)
文件“/home/amin/anaconda2/envs/rllab2/lib/python2.7/pickle.py”,第317行,保存
自我保存_全局(obj、rv)
文件“/home/amin/anaconda2/envs/rllab2/lib/python2.7/pickle.py”,第754行,保存在全局
(对象、模块、名称))
PicklingError:不能腌制。在0x7f9ab1ff07d0>处:未找到foo.lambda
构建cython的setup.py文件
setup.py
然后在终端运行:
python setup.py build_ext--inplace
有办法吗?在这段代码中
导入dill
进口泡菜
f=λx,y:x+y
s=酸洗。转储(f)
f
是一个函数,
但在另一个代码中
导入dill
进口泡菜
从foo导入foo
f=Foo()
s=酸洗。转储(f)
#或
s=dill.转储(f)
f
是一门课我是dill
的作者。扩展@DavidW在评论中所说的内容——我相信(目前)还没有已知的序列化程序可以pickle cython lambdas,或者大部分cython代码。事实上,除非C扩展代码的作者专门构建序列化指令(就像numpy
和pandas
那样),否则python序列化程序很难用C扩展来pickle对象。在这种情况下。。。您可以使用\uuuu call\uuuu
方法构建一个类,而不是lambda,这样它的行为就像一个函数。。。然后添加一个或多个pickle方法(\uuuuu reduce\uuuuuu
、\uuuu getstate\uuuuuu
、\uuuu setstate\uuuuu
或类似的方法)。。。然后您应该能够pickle类的实例。这是一项工作,但是因为这个路径已经被用于编写C++中的类——我相信你应该能为Cython构建的类工作。 <代码>泡菜< /代码>已经符合代码。你如何使用cython实现什么?@hpaulj我只是编译了我的类(foo.pyx)而不是包含pickle(test.py)的文件,当我在foo.pyx类中不使用lambda时,这是可以工作的,只要在使用lambda时出错。@kiba实际上这是行不通的。cythonlambda与Python lambda不同,我认为还没有做出任何努力使其能够pickle。通常lambdas会有一些闭包变量,我想这些变量在Cython中尤其不可pickle。
class Foo(object):
def __init__(self):
self.f = lambda x, y: x+y
import dill
import pickle
from foo import Foo
f = Foo()
s = pickle.dumps(f) # or s = dill.dumps(f)
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize("foo.pyx"))