我无法在Python2.7中使用多处理的进程之间传递dict的dict
from multiprocessing import Process, Manager
class TestProcess(Process):
def __init__(self, d, w):
super(TestProcess, self).__init__()
self.daemon = True
self.d = d
self.w = w
def run(self):
self.d['a'][self.w] = self.w
class Test(object):
def __init__(self):
manager = Manager()
self.d = manager.dict()
self.d['a'] = {}
p = TestProcess(d=self.d, w=1)
p.start()
p.join()
p = TestProcess(d=self.d, w=2)
p.start()
p.join()
def show(self):
print(self.d)
if __name__ == '__main__':
t=Test()
t.show()
期待结果:{'a':{1:1,2:2}},但得到{'a':{}}而不是
答案 0 :(得分:1)
使嵌套字典也成为代理对象:
manager = Manager()
self.d = manager.dict()
self.d['a'] = manager.dict()
或检索self.d['a']
,改变该对象并将其设置回来:
a = self.d['a']
a[self.w] = self.w
self.d['a'] = a
self.d
不是常规词典;它包含一个字典来跟踪对象本身的突变,但是与键'a'
相关联的值不是这样的对象,因此未检测到该对象的突变,并且更改没有与父流程沟通。
如果您要使用self.d['a'][self.w] = self.w
,那么self.d['a'] = self.d['a']
后者将从父进程中检索仍为空的字典,并将self.d['a']
设置回该空宾语;您有首先创建对远程可变嵌套字典的本地引用,以确保您正确地告诉父进程正确设置它。
来自文档的Proxy Objects section:
如果标准(非代理)列表或dict对象包含在引用对象中,则对这些可变值的修改将不会通过管理器传播,因为代理无法知道何时修改其中包含的值。但是,将值存储在容器代理中(在代理对象上触发
__setitem__
)确实会传播通过管理器,因此为了有效地修改这样的项,可以将修改后的值重新分配给容器代理:# create a list proxy and append a mutable object (a dictionary) lproxy = manager.list() lproxy.append({}) # now mutate the dictionary d = lproxy[0] d['a'] = 1 d['b'] = 2 # at this point, the changes to d are not yet synced, but by # updating the dictionary, the proxy is notified of the change lproxy[0] = d