Das ist ein ziemlich interessantes Verhalten, ich bin mir nicht ganz sicher, wie es funktioniert, aber ich werde einen Grund dafür finden, warum das Verhalten so ist.
Beachten Sie, dass multiprocessing.Manager().dict()
kein dict
ist, sondern ein DictProxy
-Objekt:
Der Zweck der DictProxy
-Klasse ist es, Ihnen eine dict
zu geben, die sicher über Prozesse verteilt werden kann, was bedeutet, dass sie eine Sperre zusätzlich zu den normalen dict
-Funktionen implementieren muss.
Offenbar besteht ein Teil der Implementierung hier darin, dass Sie nicht direkt auf änderbare Objekte zugreifen können, die innerhalb eines DictProxy
verschachtelt sind, denn wenn dies erlaubt wäre, könnten Sie Ihr gemeinsam genutztes Objekt so ändern, dass alle Sperren umgangen werden das macht DictProxy
sicher zu benutzen.
Hier ist ein Beweis dafür, dass Sie nicht auf veränderbare Objekte zugreifen können, was ähnlich ist wie bei setdefault()
:
Bei einem normalen Wörterbuch würden Sie erwarten, dass d['foo']
und foo
auf dasselbe Listenobjekt zeigen, und Änderungen an einem würden das andere ändern. Wie Sie gesehen haben, ist dies für die Klasse DictProxy
nicht der Fall, da die zusätzliche Prozesssicherheit durch das Multiprocessing-Modul erforderlich ist.
edit: Der folgende Hinweis aus der Multiprocessing-Dokumentation verdeutlicht, was ich oben sagen wollte:
%Vor%Hinweis: Änderungen an änderbaren Werten oder Elementen in dict- und list-Proxys werden nicht über den Manager weitergegeben, da der Proxy nicht wissen kann, wann seine Werte oder Elemente geändert werden. Um ein solches Objekt zu ändern, können Sie das geänderte Objekt dem Container-Proxy erneut zuweisen:
Anhand der obigen Informationen können Sie Ihren ursprünglichen Code so umschreiben, dass er mit DictProxy
funktioniert:
Wie Edward Loper in Kommentaren vorgeschlagen hat, wurde der obige Code bearbeitet, um get()
anstelle von setdefault()
.
Tags und Links python multiprocessing