Да! Я понял (по крайней мере, я так думаю), то есть более общая проблема выбора функции. Python такой замечательный :), я узнал большинство из них, используя функцию dir () и пару поисков в сети. Также замечательно, что это [надеюсь] решено, мне это тоже нужно.
Я не проводил много тестов на предмет того, насколько надежна эта функция co_code (вложенные fcns и т. Д.), И было бы неплохо, если бы кто-то мог посмотреть, как перехватить Python, чтобы функции могли автоматически выбираться (например, они иногда могут быть закрывающие аргументы).
Модуль Cython _pickle_fcn.pyx
# -*- coding: utf-8 -*-
cdef extern from "Python.h":
object PyCell_New(object value)
def recreate_cell(value):
return PyCell_New(value)
Файл Python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author gatoatigrado [ntung.com]
import cPickle, marshal, types
import pyximport; pyximport.install()
import _pickle_fcn
def foo(bar, baz) :
def closure(waldo) :
return baz * waldo
return closure
# really this problem is more about pickling arbitrary functions
# thanks so much to the original question poster for mentioning marshal
# I probably wouldn't have found out how to serialize func_code without it.
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_])
# reconstructing the globals is like pickling everything :)
# for most functions, it's likely not necessary
# it probably wouldn't be too much work to detect if fcn_instance global element is of type
# module, and handle that in some custom way
# (have the reconstruction reinstantiate the module)
reconstructed = types.FunctionType(code_, globals(),
name_, defaults_, closure_)
print(reconstructed(3))
ура,
Николай
РЕДАКТИРОВАТЬ - для реальных случаев необходима более надежная глобальная обработка. fcn.func_code.co_names перечисляет глобальные имена.