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):
Es scheint zu funktionieren ... Gibt es irgendwelche Probleme, die mir nicht bewusst sind? Mache ich etwas lächerlich?
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.
container.__iter__()
gibt ein Iterator-Objekt zurück. Die Iteratorobjekte selbst müssen die folgenden zwei Methoden unterstützen, die zusammen das Iteratorprotokoll bilden:
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.
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.
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%