是的!我搞定了(至少我认为是)——也就是说,更通用的问题是如何将函数序列化。Python真是太棒了:),我通过dir()函数和几次网络搜索找到了大部分答案。解决这个问题真是太好了,我也需要它。
我还没有对co_code的强健性进行过多的测试(嵌套函数等),如果有人能查一下如何钩住Python,使函数可以自动序列化(例如,它们有时可能是闭包参数),那就太好了。
Cython模块_pickle_fcn.pyx
cdef extern from "Python.h":
object PyCell_New(object value)
def recreate_cell(value):
return PyCell_New(value)
Python文件
import cPickle, marshal, types
import pyximport; pyximport.install()
import _pickle_fcn
def foo(bar, baz) :
def closure(waldo) :
return baz * waldo
return closure
fcn_instance = foo("unused?", -1)
code_str = marshal.dumps(fcn_instance.func_code)
name = fcn_instance.func_name
defaults = fcn_instance.func_defaults
closure_values = [v.cell_contents for v in fcn_instance.func_closure]
serialized = cPickle.dumps((code_str, name, defaults, closure_values),
protocol=cPickle.HIGHEST_PROTOCOL)
code_str_, name_, defaults_, closure_values_ = cPickle.loads(serialized)
code_ = marshal.loads(code_str_)
closure_ = tuple([_pickle_fcn.recreate_cell(v) for v in closure_values_])
reconstructed = types.FunctionType(code_, globals(),
name_, defaults_, closure_)
print(reconstructed(3))
干杯,
尼古拉斯
编辑 - 对于真实世界的情况需要更强大的全局处理。fcn.func_code.co_names 列出全局名称。
import
(或 execfile、eval 等)进行加载;2. 可以保存为序列化的代码对象(如 *.pyc 文件)/ 通过 marshal 将字符串转换为代码对象并执行(或 eval 等)。 - jfs