Ich verwende die Queue
Bibliothek in Python und möchte Warteschlangeneinträge eindeutig halten.
Als solches möchte ich überprüfen, ob etwas nicht bereits in der Warteschlange ist, bevor es hinzugefügt wird, im Wesentlichen eine Funktion wie diese, die in der Warteschlangenbibliothek funktioniert:
%Vor%Oder sollte ich eine andere Bibliothek / Methode verwenden, um dies zu erreichen?
Die Standardklasse Queue
kann nicht iteriert oder auf andere Weise überprüft werden.
Es wurde jedoch gebaut, um erweitert zu werden.
Erstens, wenn Sie sich die Quelle ansehen (die verlinkt ist) In den Dokumenten gibt es die Hook-Methoden _init
, _qsize
, _put
und _get
, die Sie überschreiben können, um die Implementierung zu ändern. Sehen Sie sich die Unterklassen unterhalb der Hauptklasse an und Sie können sehen, wie sie dies tun.
Es ist also einfach, die deque
-Implementierung durch eine set
:
(Ich habe _qsize
nicht implementiert, weil der Standard return len(self.queue)
in Ordnung ist.)
Jetzt müssen Sie nicht überprüfen, fügen Sie es einfach zur Warteschlange hinzu und es wird ignoriert, wenn es bereits dort ist.
Das hat natürlich den Nachteil, dass die Warteschlange nicht mehr geordnet ist. Aber Sie können das lösen, indem Sie OrderedSet
verwenden (ähnlich wie OrderedDict
in collections
). Es gibt ein Rezept , das über die collections
docs verknüpft ist. Sobald Sie das haben:
Wenn Sie tatsächlich Werte in einer Warteschlange überprüfen möchten, können Sie eine Methode dafür hinzufügen:
%Vor%Dies lädt jedoch die Rennbedingungen in Ihrem Code ein. Zum Beispiel, wenn Sie dies tun:
%Vor% Es ist immer möglich, dass x
nicht in der Warteschlange war, als Sie es überprüft haben, aber war in der Warteschlange, als Sie put
aufgerufen haben. Tatsächlich ist die einzige Verwendung dieser Funktion, bei der nicht nicht sicher ist, eine Art optimistische Überprüfung (wenn der Wert nicht in der Warteschlange ist jetzt , mach etwas teueres arbeite, dann versuche es hinzuzufügen und akzeptiere, dass die Arbeit verschwendet wird, wenn der Wert in der Zwischenzeit hinzugefügt wurde - aus dem gleichen Grund, dass Queue.full()
existiert.
Die einzige Möglichkeit, dies zu gewährleisten, besteht darin, beide Operationen unter eine Sperre zu setzen:
%Vor% Aber an diesem Punkt vereiteln Sie den Zweck der Verwendung von Queue
an erster Stelle. (Sie sind auch davon abhängig, dass Queue.mutex
ein rekursiv ausführbarer Mutex ist.) Besser, die Operation als eine Methode Ihrer Queue
-Unterklasse hinzuzufügen.
Und wenn Sie immer zuerst prüfen möchten und nur hinzufügen, wenn es nicht vorhanden ist, ist OrderedSetQueue
eine bessere Methode dafür.