作为这个问题的后续问题: 是否有一种简单的方法来挑选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数据结构(如果它很重要,它是一个很大的music21 Score对象),由于在对象结构内部某处存在弱化,它不会发痒.我以前用堆栈跟踪和python调试器调试过这样的问题,但总是很痛苦.是否有一个工具以递归方式对对象的所有属性运行dir(),查找隐藏在列表,元组,dicts等中的对象,并返回与特定值匹配的那些(lambda函数或类似的东西).一个很大的问题是递归引用,因此需要某种备忘录函数(如copy.deepcopy使用).我试过了:
import weakref
def findWeakRef(streamObj, memo=None):
weakRefList = []
if memo is None:
memo = {}
for x in dir(streamObj):
xValue = getattr(streamObj, x)
if id(xValue) in memo:
continue
else:
memo[id(xValue)] = True
if type(xValue) is weakref.ref:
weakRefList.append(x, xValue, streamObj)
if hasattr(xValue, "__iter__"):
for i in xValue:
if id(i) in memo:
pass
else:
memo[id(i)] = True
weakRefList.extend(findWeakRef(i), memo)
else:
weakRefList.extend(findWeakRef(xValue), memo)
return weakRefList
Run Code Online (Sandbox Code Playgroud)
我大概可以继续在此堵孔(在ITER是不是我想要什么类型的字典,例如),但在此之前我把更多的时间到了,如果有人知道一个更简单的回答不知道.它可能是一个非常有用的通用工具.