我正在尝试更新带有元组的集合的Manager()。list(),但无法将任何内容添加到集合中。您可以使用以下代码复制该问题:
from multiprocessing import Manager
l = Manager().list()
for _ in range(10):
l.append(set())
l[0].add((10,10)
# returns None
l[0] = {(10,10)}
# sets l[0] to {(10,10}
l[0].add((11,11))
# returns None
l[0].add(10)
# returns None
似乎由于某种原因,无论如何,add方法都会返回None
。我无法相信这是预期的行为,但也许我只是在这里遗漏了一些东西。最后,我希望能够做到的是:
l[i].add(some_tuple)
并妥善保存价值。
答案 0 :(得分:2)
答案隐藏在注意部分here中(这是Python 2.7文档,但同样适用于Python 3.x):
注意对dict和列表代理中的可变值或项目的修改不会通过管理器传播,因为代理无法知道其值或项目何时被修改。要修改此类项,可以将修改后的对象重新分配给容器代理:
# 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 # reassigning the dictionary, the proxy is notified of the change lproxy[0] = d
在您的情况下,一旦您的列表代理对象l
内部有set
个,您就可以(在任何独立的流程中都注意到您无法在 2中执行此操作同时处理 ,因为它们也是独立的对象!)执行此操作:
x = l[0]
x.append((10, 10))
l[0] = x
或者,如果您愿意:
l[0] = l[0] | set([(10, 10)])
或者当然是新奇的Python 3集语法:
l[0] = l[0] | {(10, 10)}
注意:multiprocessing.managers.ListProxy
不能(好吧, 不能,真的)直接在选定对象上实现__ior__
。虽然如果您愿意,可以使用l[0] |= ...
来编写这些内容:
l[0] |= ...
Python实际上将其实现为:
l[index]
获取值(根据需要使用锁定和/或代理),然后解锁托管对象,只返回临时对象。l[index]
(与之前一样锁定和/或代理)。这就是为什么你必须小心不要在同一时间从两个不同的进程中修改l[0]
:其中一个将首先分配,然后另一个将分配第二个,丢弃第一个 - 分配值。
答案 1 :(得分:0)
l.insert(索引,'无论你想添加什么(可能是元组)')
index是您要添加的地方,欢呼声