Ist multiprocessing.Manager (). dict (). setdefault () fehlerhaft?

8

Die its-late-and-im-wahrscheinlich-dumme Abteilung präsentiert:

%Vor%

Während:

%Vor%

Version:

%Vor%

Bug oder wug?

EDIT: Mehr von demselben, auf Python 3.2:

%Vor%

Wie kann die Liste im dict-Proxy das zusätzliche Element nicht enthalten?

    
Bittrance 29.05.2012, 22:31
quelle

3 Antworten

8

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:

%Vor%

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() :

%Vor%

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:

  

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:

%Vor%

Anhand der obigen Informationen können Sie Ihren ursprünglichen Code so umschreiben, dass er mit DictProxy funktioniert:

%Vor%

Wie Edward Loper in Kommentaren vorgeschlagen hat, wurde der obige Code bearbeitet, um get() anstelle von setdefault() .

zu verwenden     
Andrew Clark 29.05.2012, 23:09
quelle
2

Der Manager (). dict () ist ein DictProxy-Objekt:

%Vor%

DictProxy ist eine Unterklasse des BaseProxy-Typs, der sich nicht wie ein normales dict verhält: Ссылка

Es scheint also, dass Sie das mgr.dict () anders ansprechen müssen als ein basic dict.

    
Karmel 29.05.2012 23:01
quelle
0

items () gibt eine Kopie zurück. Das Anhängen an eine Kopie hat keine Auswirkungen auf das Original. Meinst du das?

%Vor%     
stark 29.05.2012 23:00
quelle

Tags und Links