Ody*_*see 3 python marshalling pickle
我试图远程了解 python2 库,这有助于通过 xmlrpc 远程运行代码。
在客户端,作者使用 marshal 转储对象,并使用 pickle 加载从服务器返回的结果:
def run(self, func, *args, **kwds):
code_str = base64.b64encode(marshal.dumps(func.func_code))
output = self.proxy.run(self.api_key, self.a_sync, code_str, *args, **kwds)
return pickle.loads(base64.b64decode(output))
Run Code Online (Sandbox Code Playgroud)
而在服务器端,他则采取相反的方式:
def run(self, api_key, a_sync, func_str, *args, **kwds):
#... truncated code
code = marshal.loads(base64.b64decode(func_str))
func = types.FunctionType(code, globals(), "remote_func")
#... truncated code
output = func(*args, **kwds)
output = base64.b64encode(pickle.dumps(output))
return output
Run Code Online (Sandbox Code Playgroud)
用 marshal 转储并用 pickle 加载结果的目的是什么?(反之亦然)
首先发送的对象marshal是一种非常特定的类型。它是一个代码对象,并且只需要支持该类型。marshal这是该模块旨在处理的类型。另一方面,返回值可以是任何类型,这取决于函数func返回的内容。该pickle模块有一个更通用的协议,可以序列化许多不同类型的对象,因此它很有可能支持返回值。
虽然您可以使用pickle在程序之间传递的两个数据项,但该marshal模块的输出对于传递代码对象来说更加紧凑和高效,因为pickle它只是环绕它。marshal如果您尝试使用and转储相同的代码对象pickle(使用协议零,Python 2 中的默认设置),您将看到来自!marshal的输出内部的输出。pickle
总而言之,该marshal模块用于发送代码,因为只需要发送代码对象,并且它是较低级别的序列化,有时可能会更高效一些。返回值被发送回来,pickle因为程序无法预测它将是什么类型的对象,并且pickle可以序列化比可以序列化更复杂的值marshal,但代价是增加一些额外的复杂性和(有时)序列化的大小。
| 归档时间: |
|
| 查看次数: |
1500 次 |
| 最近记录: |