Answers:
您可以序列化函数字节码,然后在调用方上对其进行重构。所述编组模块可以用于串行化处理的代码对象,然后可将其重新组装成一个函数。即:
import marshal
def foo(x): return x*x
code_string = marshal.dumps(foo.func_code)
然后在远程过程中(在传输code_string之后):
import marshal, types
code = marshal.loads(code_string)
func = types.FunctionType(code, globals(), "some_func_name")
func(10) # gives 100
一些警告:
元帅的格式(与此有关的任何python字节码)在主要python版本之间可能不兼容。
仅适用于cpython实现。
如果该函数引用了您需要使用的全局变量(包括导入的模块,其他函数等),则也需要对它们进行序列化或在远程端重新创建它们。我的示例只是为它提供了远程进程的全局名称空间。
您可能需要做更多的工作来支持更复杂的情况,例如闭包或生成器函数。
marshal
模块应用于序列化为的字典的字典defaultdict(lambda : defaultdict(int))
。但是它返回错误ValueError: unmarshallable object
。注意我是python2.7中的人。任何想法?谢谢
foo.func_code
引发AttributeError
。还有另一种获取功能代码的方法吗?
请查看Dill,它扩展了Python的pickle库以支持更多类型,包括函数:
>>> import dill as pickle
>>> def f(x): return x + 1
...
>>> g = pickle.dumps(f)
>>> f(1)
2
>>> pickle.loads(g)(1)
2
它还支持对函数闭包中对象的引用:
>>> def plusTwo(x): return f(f(x))
...
>>> pickle.loads(pickle.dumps(plusTwo))(1)
3
最简单的方法可能是inspect.getsource(object)
(请参阅inspect模块),该方法返回带有函数或方法的源代码的String。
的cloud
封装(PIP安装云)可以泡制任意代码,包括依赖关系。见https://stackoverflow.com/a/16891169/1264797。
code_string =''' def foo(x): 返回x * 2 def bar(x): 返回x ** 2 ''' obj = pickle.dumps(code_string)
现在
exec(pickle.loads(obj)) 富(1) > 2 酒吧(3) > 9
该模块使用的基本功能涵盖了您的查询,此外,您还可以通过网络获得最佳的压缩效果;参见说明性源代码:
y_serial.py模块::使用SQLite仓库Python对象
“序列化+持久性::在几行代码中,将Python对象压缩并注释为SQLite;然后稍后按关键字顺序按顺序检索它们,而无需任何SQL。数据库最有用的”标准”模块用于存储较少模式的数据。”
Cloudpickle可能就是您想要的。Cloudpickle描述如下:
cloudpickle对于群集计算特别有用,在群集计算中,Python代码通过网络传送以在可能接近数据的远程主机上执行。
用法示例:
def add_one(n):
return n + 1
pickled_function = cloudpickle.dumps(add_one)
pickle.loads(pickled_function)(42)
这是一个帮助程序类,您可以用来包装函数以使它们可腌制。已经提到的注意事项marshal
将适用,但是将尽一切可能使用泡菜。不会在序列化过程中保留全局或闭包。
class PicklableFunction:
def __init__(self, fun):
self._fun = fun
def __call__(self, *args, **kwargs):
return self._fun(*args, **kwargs)
def __getstate__(self):
try:
return pickle.dumps(self._fun)
except Exception:
return marshal.dumps((self._fun.__code__, self._fun.__name__))
def __setstate__(self, state):
try:
self._fun = pickle.loads(state)
except Exception:
code, name = marshal.loads(state)
self._fun = types.FunctionType(code, {}, name)