__iter __ () als Generator implementiert

8

Ich habe eine Objektunterklasse, die einen dynamischen Versand __ iter __ unter Verwendung eines Caching-Generators implementiert (ich habe auch eine Methode, den Iter-Cache zu entwerten):

%Vor%

Es scheint zu funktionieren ... Gibt es irgendwelche Probleme, die mir nicht bewusst sind? Mache ich etwas lächerlich?

    
Emanuel Landeholm 05.07.2012, 15:07
quelle

4 Antworten

1

Es scheint ein sehr fragiler Ansatz zu sein. Es reicht aus, __slots, __dc_list, __iter_cache während einer aktiven Iteration zu ändern, um das Objekt in einen inkonsistenten Zustand zu versetzen.

Sie müssen entweder das Ändern des Objekts während der Iteration verbieten oder alle Cache-Elemente auf einmal generieren und eine Kopie der Liste zurückgeben.

    
jfs 05.07.2012, 15:26
quelle
2

container.__iter__() gibt ein Iterator-Objekt zurück. Die Iteratorobjekte selbst müssen die folgenden zwei Methoden unterstützen, die zusammen das Iteratorprotokoll bilden:

%Vor%

Gibt das Iterator-Objekt selbst zurück.

%Vor%

Geben Sie das nächste Element aus dem Container zurück.

Genau das hat jeder Generator. Also keine Angst vor Nebenwirkungen.

    
Maksym Polshcha 05.07.2012 15:31
quelle
2

Es ist möglicherweise besser, die Iteration des Objekts von der Zwischenspeicherung der zurückgegebenen Werte zu trennen. Dies würde den Iterationsprozess vereinfachen und Ihnen ermöglichen, einfach zu steuern, wie das Caching durchgeführt wird und ob es zum Beispiel aktiviert ist oder nicht.

Eine andere mögliche wichtige Überlegung ist die Tatsache, dass Ihr Code die Situation, in der das Objekt, über das iteriert wird, zwischen aufeinanderfolgenden Aufrufen der Methode geändert wird, nicht vorhersehbar behandelt. Ein einfacher Weg, damit umzugehen, wäre, den Inhalt des Caches beim ersten Aufruf vollständig aufzufüllen und dann nur yield , was es für jeden Aufruf enthält - und das Verhalten zu dokumentieren.

    
martineau 05.07.2012 16:09
quelle
0

Was Sie tun, ist gültig, wenn auch seltsam. Was ist ein __slots oder ein __dc_list ?? Im Allgemeinen ist es besser, den Inhalt Ihres Objekts in einem Attributnamen und nicht in seinem Typ zu beschreiben (zB: self.users statt self.u_list).

Sie können meinen LazyProperty -Dekorierer verwenden, um dies wesentlich zu vereinfachen.

Schmücken Sie einfach Ihre Methode mit @LazyProperty. Es wird das erste Mal aufgerufen, und der Dekorator wird dann das Attribut durch die Ergebnisse ersetzen. Die einzige Voraussetzung ist, dass der Wert wiederholbar ist. es hängt nicht vom veränderlichen Zustand ab. Sie haben diese Anforderung auch in Ihrem aktuellen Code mit Ihrem selbst .__ iter_cache.

%Vor%     
bukzor 05.07.2012 16:37
quelle