@maxwell: Das `enumerate()` und Index müssest Du natürlich mit dem Iterieren über eine Kopie der Liste verbinden, damit Du nicht aus der Liste löschst, über die iteriert wird. Aber auch da ist algorithmisch der Weg, den Du jetzt gegangen bist besser, denn das Löschen bedeutet ja auch, das alle Elemente danach umkopiert werden müssen, während bei der aktuellen Lösung jedes Element in amortisiert O(1)-Laufzeit kopiert wird.
Das `match()` auf den `item`-Objekten in meinem Beispiel macht was immer Du dafür implementierst. Zum Beispiel die Bitoperationen.
Jetzt sag bitte nicht, das `ol` und `nw` für `old` und `new` stehen!?
Das wäre aus dem gleichen Grund schlimm, warum auch Bitoperationen schlecht sind: Es verwirrt den Leser des Quelltextes. Ich habe nämlich gerade festgestellt, dass `item.match()` eher ein `contains()` wäre und man damit sogar noch etwas hübscher den ``in``-Operator überladen könnte.
Methodennamen sollten Tätigkeiten widerspiegeln und möglichst nur *eine*. Hier sind die Tätigkeit*en* als Konstanten über das `how`-Argument angegeben und man muss die Methode mehrfach lesen um zu verstehen was in welchem Fall eigentlich gemacht wird. Und auch bei den Werten gibt es zu viele Sonderfälle. Wenn man nichts verändern will, sollte man die Methode halt einfach nicht aufrufen. Blockieren, Entblockieren und Setzen macht ohne Bitmaske keinen Sinn. Falls die Methode dann trotzdem einen Effekt hat, stecken da ja noch mehr Funktionalitäten drin. Die Anzahl der Ausführungspfade, die man dann verstehen muss verdoppelt sich damit auf 6 beziehungsweise 8, wenn man noch "beliebige" Werte für `how` mit dazu nimmt.
Statt der Bitmasken wären Mengen die offensichtlichste Wahl als Python-Datenstruktur. Wenn man die ganzen Sonderfälle und Mikrooptimierungen rausnimmt, könnte das so aussehen:
Code: Alles auswählen
def send_pending(self):
pending = list()
for signal in self.pset.pending:
if signal.type not in self.pset.blocked_signals:
self.send(signal)
else:
pending.append(signal)
self.pset.pending = pending
def set_blocked_signals(self, signals):
self.pset.blocked_signals = signals
self.send_pending()
def block_signals(self, signals):
self.set_blocked_signals(self.pset.blocked_signals | signals)
def unblock_signals(self, signals):
self.set_blocked_signals(self.pset.blocked_signals - signals)