我使用python管理器在进程之间共享数据。我想把我的代码分解成更小的片段,并创建一个函数“soFactory”,它将获取一个名称/对象对字典,并以给定的名称向管理器注册对象。 在下面的简单示例中,我创建了两个列表并向管理器注册它们。如果我使用soFactory,经理只返回一个列表(最后一个注册的列表),而不管我引用哪个名称。 如果我解开了soFactory的逻辑,我就可以通过引用它们的注册名称来访问正确的对象。 我一定错过了一些明显的东西,但没有看到它。你知道吗
# ------------ prototype for SO question -------
from sys import stderr
def soFactory(dictofSo, manager):
"""shared object factory"""
for n,t in dictofSo.items():
print >>stderr, 'created item',n,t
manager.register(n, callable=lambda: t)
def soRoutine(n, t, manager):
manager.register(n, callable=lambda: t)
def test_soFactory(useFactory=True):
"""tests the soFactory function"""
from multiprocessing import managers
m = managers.BaseManager(address='/var/tmp/tqps-test', authkey='abc123')
mySOlist = {'L1': [1],'L2':[2]}
if useFactory:
soFactory(mySOlist, m)
else:
for n, t in mySOlist.items():
soRoutine(n, t, m)
m.start()
m.L1().append('only in L1!')
print >>stderr, m.L1(), m.L2()
>>> test_soFactory()
created item L2 [2]
created item L1 [1]
[1, 'only in L1!'] [1, 'only in L1!']
>>> test_soFactory(useFactory=False)
[1, 'only in L1!'] [2]
>>>
这是一个常见的python变量作用域陷阱,这是由于
lambda
创建的闭包记住了变量的名称,而不是对象(或“指针”)。调用lambda
时,t
的值是在周围的范围内查找的,此时循环已经结束,所以t
分配了它的最终值L1
,当然,这取决于dictofSo.items()
返回值的顺序。你知道吗您可以通过打开
multiprocessing
的调试日志来确认这一点:L1
和L2
具有相同的id:在函数
soRoutine()
中创建lambda
时,因为函数将创建一个新的局部作用域,所以这次t
可能会指向您期望的值。另见this post。你知道吗相关问题 更多 >
编程相关推荐