2013-04-02 3 views
8

Ich verwende das readline Modul mit Python 2.7.3 mit Fedora 17. Ich habe dieses Problem nicht mit Ubuntu 12.10.Python readline Modul druckt Escape-Zeichen beim Import

Während import readline wird ein Escape-Zeichen angezeigt.

$ python -c 'import readline' |less 
ESC[?1034h(END) 

Normalerweise, wenn ich unerwartet Ausgabe wie diese zu erhalten, behandeln ich es stdout/stderr Umleitung zu einem Dummy-Dateideskriptor (Beispiel unten) verwendet wird. Aber dieses Mal funktioniert diese Methode nicht.

import sys 

class DummyOutput(object): 
    def write(self, string): 
     pass 

class suppress_output(object): 
    """Context suppressing stdout/stderr output. 
    """ 
    def __init__(self): 
     pass 
    def __enter__(self): 
     sys.stdout = DummyOutput() 
     sys.stderr = DummyOutput() 
    def __exit__(self, *_): 
     sys.stdout = sys.__stdout__ 
     sys.stderr = sys.__stderr__ 

if __name__ == '__main__': 
    print 'Begin' 
    with suppress_output(): 
     # Those two print statements have no effect 
     # but *import readline* prints an escape char 
     print 'Before importing' 
     import readline 
     print 'After importing' 
    # This one will be displayed 
    print 'End' 

Wenn Sie diese Schnipsel in einem test.py Skript ausführen, werden Sie in dem suppress_output Kontext sehen, dass die print Aussagen sind in der Tat unterdrückt, aber nicht die Flucht char.

$ python test.py |less 
Begin 
ESC[?1034hEnd 
(END) 

hier sind also meine zwei Fragen:

  1. Wie ist es möglich, dass dieses Escape-Zeichen durch zu bekommen?
  2. Wie man es unterdrückt?
+1

Sieht aus wie das Modul will den Terminal-Status mit einer Escape-Sequenz ändern, aber das funktioniert nicht. Sie sollten nicht versuchen, das zu umgehen, sondern das stattdessen beheben. – wRAR

+0

Ja, es gibt einen Workaround, der auf dem http://reinout.vanrees.org/weblog/2009/08/14/readline-invisible-character-hack.html basiert. Aber das hat meine erste Frage nicht beantwortet :) (und ich hatte Angst, dass das nicht sehr tragbar ist, aber ich könnte falsch liegen). – Alex

+0

Ich vermute, dass Ihr Terminal und/oder terminfo DB dieses Problem verursachen. – wRAR

Antwort

0

die erste Frage zu beantworten: sys.stdout Ändern stdout nicht wirklich beeinflussen, was stdout's file descriptor is pointing at Datei, sondern nur, was High-Level-Dateiobjekt Python betrachtet werden. Anders gesagt, die Änderung sys.stdout wirkt sich auf Ihren Python-Code aus, aber nicht (allgemein) auf kompilierte Erweiterungen, die Sie verwenden (wie das readline-Modul). All dies gilt auch für sys.stderr.

Um die zweite zu beantworten: Sie können tun, was this answer schlägt (was sollte einfach zu Python zu portieren). Obwohl die Vorschläge in den Kommentaren klingen wie ein besserer Weg.

+0

hier ist [wie stdout auf C-Ebene in Python umleiten] (http://Stackoverflow.com/a/22434262/4279) – jfs

0

Ich habe den folgenden Hack benutzt, bevor Readline- Import

import os 
if os.environ['TERM'] == 'xterm': 
    os.environ['TERM'] = 'vt100' 
# Now it's OK to import readline :) 
import readline 
+1

das Problem erscheint auch mit ' xterm-256color' –

+0

aber 'os.environ ['TERM'] setzen = ''' dann 'readline' importieren und dann' os wiederherstellen.environ ['TERM'] 'zurück zu dem, was es vorher war, vermeidet das Drucken der Escape-Sequenz (nicht sicher über andere Funktionalität von' readline' obwohl ...) –

1

hier ist das, was ich verwende (zugegebenermaßen basierend auf @jypeter ‚s Antwort), nur die TERM Umgebungsvariable Clearing, wenn der Ausgang nicht tut gehe zu einem tty (zB wird in eine Datei umgeleitet):

if not sys.stdout.isatty(): 

    # remember the original setting 
    oldTerm = os.environ['TERM'] 

    os.environ['TERM'] = '' 

    import readline 

    # restore the orignal TERM setting 
    os.environ['TERM'] = oldTerm 

    del oldTerm