Der aktuelle Docstring in der Spinner- Klasse zeigt die Verwendung von s.next()
zum Aktualisieren des Spinners. Aber dies ist ein Python 2-ism, der für Iteratoren in Python 3 nicht mehr existiert. Stattdessen wäre die korrekte Dokumentation next(s)
.
Außerdem finde ich es verwirrend, dass sich die API für Spinner
so stark von ProgressBar
und ProgressBarOrSpinner
. In den beiden letzteren Fällen gibt ihre Methode __enter__
(bei Verwendung von with ProgressBar(...) as bar:
die ProgressBar(OrSpinner)
Instanz selbst zurück, die selbst iterierbar ist. Sie stellt auch eine update()
Methode bereit die aufgerufen werden kann, um den Fortschrittsbalken zu aktualisieren, während with Spinner(...) as s:
nicht die Spinner
Instanz selbst zurückgibt, sondern einen Generator.
Es sollte einfach sein, die API für Spinner
zu aktualisieren (sie iterierbar machen, __enter__
die Spinner
Instanz zurückgeben und eine update()
Methode hinzufügen), damit es ist eher wie ProgressBar
.
Ich würde vorschlagen, die Aktualisierungen auf Spinner
vorzunehmen und gleichzeitig die Dokumentation zu korrigieren.
Ich arbeite daran
So. Wenn wir den Spinner iterierbar machen, hat er keine Stoppbedingung. Wenn sich der Benutzer also für eine abenteuerliche Schleife (wie unten) entscheidet, werden wir heute nicht in den Weltraum gehen
for s in console.Spinner("Reticulating splines", file=stream, chars=chars):
foo_bar()
Vielleicht ist es besser, den Generator einfach in eine update()- Funktion umzuschreiben (und dabei die __enter__
__exit__
Methoden zu verlassen)? Oder sollten wir uns über diesen Anwendungsfall keine Sorgen machen.
Das ist ein guter Punkt und deckt eine weitere Inkonsistenz zwischen Spinner
und ProgressBar
, wobei letztere eine Länge/einen Iterator als Argument annehmen kann. Dies ist sinnvoll, da ein Fortschrittsbalken eher für etwas mit bekanntem Arbeitsaufwand steht, während ein Spinner für einen unbekannten Arbeitsaufwand steht. Obwohl Iteratoren manchmal nicht endlich sind, wäre es nützlich, einen solchen Iterator in einen Spinner zu packen.
Trotzdem ist Ihr for-Schleifenbeispiel immer noch nützlich (obwohl es auch mit einer with
Anweisung verwendet würde, um den Spinner ordnungsgemäß abzubrechen, wenn Sie fertig sind, wie:
with Spinner('message') as spin:
for _ in spin:
# do stuff
break
Dies entspricht einer while True:
Schleife, aus der Sie schließlich break
herausnehmen müssen, außer dass der Spinner während der Schleife aktualisiert wird.
In der Zwischenzeit würde eine update()
Methode nur dem Aufrufen von next(spinner)
.
Im Grunde wäre dies Sache von:
Spinner.__init__
so, dass es self._iter = self._iterator()
(oder self._silent_iterator
) tut.__enter__
in nur return self
und füge auch __iter__
was dasselbe tut ( return self
)__next__
was next(self._iter)
update()
was next(self)
aufruft