Print Ausgabe im Webbrowser nacheinander, nicht auf einmal?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
luckystriker
User
Beiträge: 6
Registriert: Dienstag 23. Mai 2017, 14:17

Hallo Zusammen,

ich schreibe momentan ein kleines Skript, um es nachher über eine Webseite aufzurufen.
Funktionsfähig ist es schon, und nun arbeite ich gerade an den "Feinheiten". Im Zuge dessen ist mir aufgefallen, dass sämtliche Print-Ausgaben auf einmal im Browser angezeigt werden. Ganz gleich, ob dazwischen eine Funktion aufgerufen wird, die ein wenig Zeit benötigt, wird noch bevor der return-code der Funktion angekommen ist, das dahinterliegende Print schon ausgegeben.

Beispielsweise:
print "Berechnung wird gestartet"
subprocess.Popen([irgend, eine, funktion])
print "Berechnung abgeschlossen"
print "Ergebnis: -> "
Soll-Ausgabe im Browser:
>>> Berechnung wird gestartet.
<Pause, da Funktion im Hintergrund ausgeführt wird>
>>> Berechnung abgeschlossen.
>>> Ergebnis: -> []
Ist-Zustand im Browser:
<Pause. Die Funktion wird bearbeitet, die Ladeanzeige dreht und dreht.>
>>> Berechnung wird gestartet.
>>> Berechnung abgeschlossen.
>>> Ergebnis: -> []

Es wird gewartet, und gerödelt, bis dann letztendlich alles auf einmal erscheint. Das eliminiert aber den Zweck dieser Ausgabe, da ich ja den Anwender vorher informieren möchte was geschieht, und nicht erst nachher. Die Abarbeitung der Funktion benötigt einige Sekunden, so dass man es auf jeden fall sehen müsste. Ich habe auch schon folgendes probiert:

in einer neuen Test-Datei:

Code: Alles auswählen

text = "lorem ipsum"
i = 0
while i < 100:
	print text
	i = i + 1
Auch hier wird gewartet bis zum Schluss, und alles auf einmal ausgegeben, also 100x "lorem ipsum" untereinander.
Ich hätte jedoch gerne die Ausgabe Zeile für Zeile, einzeln nacheinander.

Ich habe auch bereits sys.stdout.flush() nach der print-Anweisung probiert, jedoch hat das keinen merklichen Effekt bei mir gehabt. Um eventuell die Zeit ein wenig zu verlängern, habe ich auch schon versucht über time.sleep(1) ein wenig mehr Latenz reinzubekommen, leider erfolglos.

Darüber hinaus verstehe ich eine Sache noch nicht ganz. Ich habe in Version 1 meines Skripts den gesamten Inhalt direkt im Skript ausgeführt. Ich habe keine Funktionen bzw. Methoden definiert. Ich dachte dann, dass es vllt. daran liegen könnte, und habe den Code-Inhalt funktional in Methoden unterteilt. So stehen nun auch Print-Ausgaben alleine schon methodisch voneinander getrennt. Jedoch wird auch hier bis zum Ende der Skript-Abarbeitung gewartet. Selbst eine Print-Ausgabe direkt unter den "import"-Anweisungen wird zur gleichen Zeit ausgegeben, wie das letzte "print" in der zuletzt genutzten Methode. Warum ist das so?

Jemand eine Ahnung, wie ich hier vorgehen kann, um eine "dynamischere" Ausgabe umzusetzen? :?

Viele Grüße und danke im Voraus!
Lucky
BlackJack

@luckystriker: So funktioniert HTTP nun einmal. Der Client stellt eine Anfrage, der Server erstellt die Antwort und schickt sie zum Client, und der stellt sie dar. Clients *können* schon anfangen die Antwort darzustellen bevor sie komplett angekommen ist, aber ob und wie sie das machen ist nichts was garantiert ist.

Um das dynamischer zu machen, muss man deutlich mehr Aufwand betreiben. Auf beiden Seiten. Also auf Clientseite zum Beispiel auch einen Programmteil schreiben, wenn es im Browser laufen soll, also in JavaScript oder einer Sprache die sich nach JavaScript übersetzen lässt (CoffeeScript, Dart, …).
luckystriker
User
Beiträge: 6
Registriert: Dienstag 23. Mai 2017, 14:17

Hi BlackJack,

wenn du es so sagst, dann komm ich mir grad ziemlich bekloppt vor. :D Hast recht.
Danke für den Hinweis. :)

Ist übrigens ein super Forum hier. Man kriegt hier schnelle, schöne Antworten. Das ist lang nicht in jedem Forum so.

Viele Grüße
Lucky 8)
Benutzeravatar
BigZ
User
Beiträge: 30
Registriert: Mittwoch 1. Juli 2015, 21:18
Wohnort: Hamburg
Kontaktdaten:

Wie BlackJack schon sagte,
alles was der Server tut braucht halt seine Zeit und wird dann in einem Rutsch zurück gegeben.
In deinem Fall kannst du aber die Strings durch JavaScript ausgeben lassen und nur das Ergebnis des Servers als Json an das clientseitig laufende JavaScript zurück geben.
Das ergibt zumindest den Effekt den du dir wünschts.
Wenn du ganz mutig bist, kannst du dich aber auch ein bisschen in asynchrone Requests server- und clientseitig rein fuchsen.
Das ist die etwas aufwendigere Methode von der BlackJack sprach *senf dazu geb* Bild
"Ist noch λ?"
"Ja, aber das ϕ ist noch ϱ"
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@luckystriker: natürlich geht das, das nennt sich Chunked Transfer und die meisten Browser stellen den Inhalt auch sofort dar, so dass man die Übertragung beobachten kann.
Hier ein Beispiel mit bottle:

Code: Alles auswählen

import bottle
import time

@bottle.route("/")
def count():
    for x in range(1000):
        yield "%d\n"%x
        time.sleep(1)

bottle.run()
Antworten