作为这个问题的后续问题: 是否有一种简单的方法来挑选python函数(或以其他方式序列化其代码)?
我想从上面的帖子中看到这个子弹的一个例子:
"如果函数引用了你需要选择的全局变量(包括导入的模块,其他函数等),你也需要对它们进行序列化,或者在远程端重新创建它们.我的例子只是给它了远程进程的全局命名空间. "
我有一个简单的测试,我正在使用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)
Run Code Online (Sandbox Code Playgroud)
然后我开始一个新的python实例:
file = open('/tmp/f2.txt', 'r')
code = marshal.loads(file.read())
func2 = types.FunctionType(code, globals(), "some_func_name");
func2('blah')
Run Code Online (Sandbox Code Playgroud)
这导致:
NameError: global name 'g' is not defined
Run Code Online (Sandbox Code Playgroud)
这与我所采用的不同方法无关.我尝试了基本相同的方法来发送g作为f但f仍然看不到g.如何进入全局命名空间,以便f在接收过程中可以使用它?
有人还建议将pyro作为如何执行此操作的示例.我已经尝试了解迪斯科项目中的相关代码.我拿了他们的dPickle类并尝试在独立应用程序中重新创建他们的disco/tests/test_pickle.py功能但没有成功.我的实验在使用转储调用执行函数编组时遇到了问题.无论如何,也许接下来就是热探索.
总之,我所遵循的基本功能是能够通过线路发送方法并将所有基本的"工作空间"方法与其一起发送(如g).
来自答案的更改示例:
工作函数编写者:
import marshal, types
def g(blah):
print blah
def f():
for i in range(1,5):
print 'some function f'
g('blah string used …Run Code Online (Sandbox Code Playgroud) 我已经尝试了多种方法来挑选具有依赖关系的python函数,遵循StackOverflow上的许多建议(例如dill,cloudpickle等),但似乎都遇到了一个我无法弄清楚的基本问题.
我有一个主模块,试图从导入的模块中挑选一个函数,通过ssh发送它以进行unickled并在远程机器上执行.
所以主要有:
import dill (for example)
import modulea
serial=dill.dumps( modulea.func )
send (serial)
Run Code Online (Sandbox Code Playgroud)
在远程机器上:
import dill
receive serial
funcremote = dill.loads( serial )
funcremote()
Run Code Online (Sandbox Code Playgroud)
如果被腌制和发送的函数是main本身定义的顶级函数,那么一切正常.当它们位于导入的模块中时,加载功能将失败,并显示"未找到模块模块"类型的消息.
模块名称似乎与函数名称一起被腌制.我没有看到任何方法来"修复"pickle以消除依赖关系,或者在接收器中创建一个虚拟模块以成为unpickling的接收者.
任何指针都将非常感激.
--prasanna