在进程之间传递字典

passing dict of dict between process

我无法在 Python2.7

中使用多处理在进程之间传递一个字典
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':{}}

也使嵌套字典成为代理对象:

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 不是正规词典;它包装了一个 dict 来跟踪对象本身的突变,但是与键 'a' 关联的 value 不是这样的对象,因此未检测到该对象的突变,并且更改不会与父进程通信。

如果你要使用 self.d['a'][self.w] = self.w,那么 self.d['a'] = self.d['a'] 后者会 从父进程 中检索仍然空的字典并设置 self.d['a'] 回到那个空对象;您必须首先创建对远程可变嵌套字典的本地引用,以确保您正确地告诉父进程正确设置它。

来自文档的 Proxy Objects section

If standard (non-proxy) list or dict objects are contained in a referent, modifications to those mutable values will not be propagated through the manager because the proxy has no way of knowing when the values contained within are modified. However, storing a value in a container proxy (which triggers a __setitem__ on the proxy object) does propagate through the manager and so to effectively modify such an item, one could re-assign the modified value to the container proxy:

# 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