Unter Eingabe von sys.stdin, non-blocking
Arbeite ich an einem bot für ein Wettbewerb, der bekommt seinen input über sys.stdin
und verwendet Python ' s print()
für die Ausgabe. Ich habe Folgendes:
import sys
def main():
while True:
line = sys.stdin.readline()
parts = line.split()
if len(parts) > 0:
# do stuff
Das problem ist, dass der input kommt über einen Bach und unter Verwendung der oben, blockiert mich vom Druck etwas zurück, bis der stream geschlossen wird. Was kann ich tun, um diese Arbeit zu machen?
- vielleicht eine duplizieren
- Non-blocking auf stdin entweder nicht oder funktioniert nicht sehr zuverlässig. Sie erlaubt die Verwendung von threading/multiprocessing? Ursache, die funktionieren sollte
Du musst angemeldet sein, um einen Kommentar abzugeben.
Durch drehen blockieren ausgeschaltet, können Sie nur Lesen ein Zeichen in einer Zeit. Also, es gibt keinen Weg, um
readline()
arbeiten in einer non-blocking-Kontext. Ich nehme an, Sie wollen einfach nur read-Taste drückt, um den Roboter zu Steuern.Hatte ich kein Glück mit
select.select()
auf Linux und die Möglichkeit geschaffen, mit tweakingtermios
Einstellungen. So, das ist Linux-spezifisch, aber funktioniert bei mir:Besser Windows oder cross-Plattform-Antwort finden Sie hier: Python-nicht blockierende Konsolen-Eingabe
tty.setraw()
), aber dann Sie haben, um es zu gekocht-Modus nach, der.Können Sie Selektoren für Griff-I/O-multiplexing:
https://docs.python.org/3/library/selectors.html
Probieren Sie es aus:
Dem obigen code wird halten Sie auf der Linie
bis ein registriertes event Auftritt, wird die Rücksendung eines selector_key Instanz (k) und eine Maske der zu überwachenden Ereignisse.
In dem obigen Beispiel haben wir nur registriert, ein Ereignis (Enter-Taste drücken):
Den Selektor Schlüssel-Instanz ist wie folgt definiert:
Daher, die register-Methode sets-k.Daten, wie Sie unsere callback-Funktion got_keyboard_data, und nennt es, wenn die Geben Sie - Taste gedrückt wird :
Ein vollständigeres Beispiel (und hoffentlich nützlicher) wäre die multiplex stdin Daten von Benutzer ankommende verbindungen aus dem Netzwerk:
Können Sie testen, mit zwei Klemmen.
erste terminal:
öffnen Sie ein weiteres terminal und führen:
zurück zu der ersten
Ergebnis (gesehen auf der main terminal):
Dürfte ich vorschlagen
nobreak
? Wenn ' N Sie bereit sind zu verwenden, Flüche.https://docs.python.org/3/library/curses.html#curses.window.nodelay
Verwenden einen generator, der - zum Glück
sys.stdin
ist bereits ein generator!Einen generator ermöglicht Ihnen die Arbeit auf einem unendlichen Strom. Immer, wenn Sie es nennen, es gibt das nächste element. Um einen generator benötigen Sie das
yield
Stichwort.Nicht vergessen, ein
break
- Anweisung in die Schleife, wenn eine bestimmte, wünschte situation passiert.Finden Sie weitere Informationen über Generatoren auf:
for line in sys.stdin: ...
oder die neuerefileinput
Modul. weder sind nicht-blockierend, wenn.