Frage

Ich habe eine Python-basierte Anwendung, die ein paar Befehle in einer einfachen Lese-eval-print-Schleife annehmen kann. Ich verwende raw_input('> ') den Eingang zu erhalten. Auf Unix-basierten Systemen, ich import readline auch Dinge verhalten sich ein wenig besser zu machen. Das alles funktioniert gut.

Das Problem ist, dass es asynchrone Ereignisse kommen in, und ich möchte Ausgabe drucken, sobald sie auftreten. Leider macht diese Dinge hässlich aussehen. Der „>“ string zeigt nicht wieder nach dem Ausgang, und wenn der Benutzer auf halbem Weg durch etwas Eingabe ist, es hackt ihren Text in zwei Hälften. Es soll wohl den Benutzer Text-in-progress neu gezeichnet nach etwas gedruckt wird.

Dies scheint, wie es ein Problem gelöst sein muss. Was ist der richtige Weg, dies zu tun?

Beachten Sie auch, dass einige meiner Benutzer sind Windows-basiert.

TIA

Edit: Die akzeptierte Antwort arbeitet unter Unixy Plattformen (wenn das Readline- Modul verfügbar ist), aber wenn jemand weiß, wie man diese Arbeit unter Windows zu machen, wäre es sehr zu schätzen

War es hilfreich?

Lösung

Vielleicht wie etwas, das wird es tun:

#!/usr/bin/env python2.6

from __future__ import print_function

import readline
import threading

PROMPT = '> '

def interrupt():
    print() # Don't want to end up on the same line the user is typing on.
    print('Interrupting cow -- moo!')
    print(PROMPT, readline.get_line_buffer(), sep='', end='')

def cli():
    while True:
        cli = str(raw_input(PROMPT))

if __name__ == '__main__':
    threading.Thread(target=cli).start()
    threading.Timer(2, interrupt).start()

Ich glaube nicht, dass stdin Thread-sicher ist, so dass Sie Zeichen an die Unterbrechung Faden zu verlieren (dh der Benutzer am Ende der interrupt erneut eingeben muß) können am Ende. Ich übertrieb die Menge an interrupt Zeit mit dem time.sleep Anruf. Der readline.get_line_buffer Anruf wird nicht die Zeichen anzeigen, die verloren gehen, so dass es alle stellt sich heraus in Ordnung.

Beachten Sie, dass stdout sich nicht sicher ist, fädeln, so dass, wenn Sie mehrere Ausführungs-Threads haben unterbrechen, kann dies noch grob am Ende aussehen.

Andere Tipps

Warum schreiben Sie Ihre eigene REPL mit raw_input()? Haben Sie bei der cmd.Cmd Klasse aussehen? Edit: Ich habe gerade die sclapp Bibliothek, die kann auch nützlich sein.

Hinweis: die cmd.Cmd Klasse (und sclapp) können oder auch nicht direkt Ihr ursprüngliches Ziel unterstützen; Sie kann es zu Unterklasse haben und es zu ändern, wie diese Funktion zur Verfügung zu stellen benötigt.

laufen diese:

python -m twisted.conch.stdio

Sie erhalten eine schöne, farbige, async REPL bekommen, ohne Gewinde mit . Während Sie in der Eingabeaufforderung eingeben, wird die Ereignisschleife ausgeführt wird.

Blick in den Code-Modul, es können Sie Objekte erstellen für die Interpretation Python-Code auch (schamlose Werbung) https: // github.com/iridium172/PyTerm können Sie interaktive Kommandozeilen-Programme erstellen, die roh Tastatureingaben verarbeiten (wie ^ C eine KeyboardInterrupt erhöhen).

Es ist so eine Art Nicht-Antwort, aber ich würde Blick auf IPython 's-Code sehen, wie sie es tun.

Ich glaube, Sie haben zwei grundlegende Optionen:

  1. Synchronisieren Sie Ihre Ausgabe
  2. (das heißt Block, bis er zurückkommt)
  3. Trennen Sie Ihre Eingabe und Ihren (asynchronen) -Ausgang, vielleicht in zwei getrennten Spalten.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top