gpt4 book ai didi

python - 如何使用其依赖项来 pickle python 函数?

转载 作者:太空狗 更新时间:2023-10-29 17:12:26 28 4
gpt4 key购买 nike

作为这个问题的后续: Is there an easy way to pickle a python function (or otherwise serialize its code)?

我想从上面的帖子中看到这个子弹的例子:

“如果该函数引用了您需要获取的全局变量(包括导入的模块、其他函数等),您也需要将它们序列化,或者在远程端重新创建它们。我的示例只是为它提供了远程进程的全局命名空间。”

我有一个简单的测试,我正在使用 marshal 将函数字节代码写入文件:

def g(self,blah): 
print blah

def f(self):
for i in range(1,5):
print 'some function f'
g('some string used by g')

data = marshal.dumps(f.func_code)

file = open('/tmp/f2.txt', 'w')
file.write(data)

然后启动一个新的 python 实例:

file = open('/tmp/f2.txt', 'r')
code = marshal.loads(file.read())
func2 = types.FunctionType(code, globals(), "some_func_name");
func2('blah')

这导致:

NameError: global name 'g' is not defined

这独立于我为包含 g 而采用的不同方法。我尝试了基本相同的方法将 g 发送给 f,但 f 仍然看不到 g。如何将 g 放入全局命名空间,以便 f 在接收进程中使用它?

有人还建议查看 pyro 作为如何执行此操作的示例。我已经尝试理解 disco 项目中的相关代码。我参加了他们的 dPickle 类(class),并尝试在独立应用程序中重新创建他们的 disco/tests/test_pickle.py 功能,但没有成功。我的实验在使用 dumps 调用进行函数编码时遇到了问题。不管怎样,也许下一步是火法探索。

总而言之,我所追求的基本功能是能够通过线路发送一个方法,并让所有基本的“工作区”方法都随之发送(比如 g)。

答案变化的例子:

工作函数_writer:

import marshal, types

def g(blah):
print blah


def f():
for i in range(1,5):
print 'some function f'
g('blah string used by g')


f_data = marshal.dumps(f.func_code)
g_data = marshal.dumps(g.func_code);

f_file = open('/tmp/f.txt', 'w')
f_file.write(f_data)

g_file = open('/tmp/g.txt', 'w')
g_file.write(g_data)

工作函数_reader:

import marshal, types

f_file = open('/tmp/f.txt', 'r')
g_file = open('/tmp/g.txt', 'r')

f_code = marshal.loads(f_file.read())
g_code = marshal.loads(g_file.read())

f = types.FunctionType(f_code, globals(), 'f');
g = types.FunctionType(g_code, globals(), 'g');

f()

最佳答案

2020 年 9 月更新:请参阅下方@ogrisel 的评论。在 2013 年我写下这个答案的原始版本后不久,PiCloud 的开发人员就转移到了 Dropbox,尽管七年后很多人仍在使用 cloudpickle 模块。该模块进入了 Apache Spark,并在其中继续得到维护和改进。我正在相应地更新下面的示例和背景文本。

云 pickle

cloudpickle package 能够 pickle 一个函数、方法、类,甚至是一个 lambda,以及任何依赖项。要试用它,只需 pip install cloudpickle 然后:

import cloudpickle

def foo(x):
return x*3

def bar(z):
return foo(z)+1

x = cloudpickle.dumps(bar)
del foo
del bar

import pickle

f = pickle.loads(x)
print(f(3)) # displays "10"

换句话说,只需调用 cloudpickle.dump()cloudpickle.dumps() 就像使用 pickle.*,然后使用 native pickle.load()pickle.loads() 解冻。

背景

PiCcloud.com 发布了 LGPL 下的 cloud python 包,其他开源项目很快开始使用它(google for cloudpickle.py 看几个) . picloud.com 的人们有动力努力使通用代码 pickling 工作——他们的整个业务都是围绕它建立的。这个想法是,如果您有 cpu_intensive_function() 并想在 Amazon 的 EC2 网格上运行它,您只需替换:

cpu_intensive_function(some, args) 

与:

cloud.call(cpu_intensive_function, some, args)

后者使用 cloudpickle 来提取任何依赖的代码和数据,将其发送到 EC2,运行它,并在您调用 cloud.result() .

Picloud 以毫秒为单位计费,便宜得要命,我一直用它来进行蒙特卡罗模拟和金融时间序列分析,当时我需要数百个 CPU 内核,每个内核只需几秒钟。多年后,我仍然无法对它说足够多的好话,我什至没有在那里工作。

关于python - 如何使用其依赖项来 pickle python 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10048061/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com