2013-04-02 11 views
8

Używam modułu readline z Pythonem 2.7.3 z Fedorą 17. Nie mam tego problemu z Ubuntu 12.10.Moduł readline Pythona drukuje znak escape podczas importowania

Podczas import readline wyświetlany jest znak escape.

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

Zwykle kiedy się nieoczekiwane wyjście tak, ja obsługiwać go za pomocą stdout/stderr przekierowanie do manekina deskryptor pliku (przykład poniżej). Ale tym razem ta metoda nie działa.

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' 

Jeśli uruchomić ten fragment w test.py skryptu, widać, że wewnątrz kontekstu suppress_output, oświadczenia print są rzeczywiście tłumione, ale nie char ucieczki.

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

Więc oto moje dwa pytania:

  1. Jak to możliwe, postać ta ucieczka przejść przez?
  2. Jak to powstrzymać?
+1

Wygląda na to, że moduł chce zmienić stan terminala za pomocą sekwencji specjalnej, ale to nie działa. Nie powinieneś próbować tego obejść, napraw to. – wRAR

+0

Tak, istnieje sposób obejścia tego na podstawie http://reinout.vanrees.org/weblog/2009/08/14/readline-invisible-character-hack.html. Ale to nie odpowiadało na moje pierwsze pytanie :) (i bałam się, że nie był bardzo przenośny, ale mogę się mylić). – Alex

+0

Podejrzewam, że twój terminal i/lub terminfo DB powoduje ten problem. – wRAR

Odpowiedz

0

Aby odpowiedzieć na pierwsze pytanie: zmiana sys.stdout faktycznie nie wpływa na to, co złożyć stdout's file descriptor is pointing at, lecz tylko to, co obiekt pliku wysokim poziomie Python uważa się standardowe wyjście. Powiedział inaczej, zmieniając kod w języku Python, ale nie (ogólnie) żadnych skompilowanych rozszerzeń, których możesz używać (np. Moduł readline). Wszystko to dotyczy również sys.stderr.

Aby odpowiedzieć na drugie pytanie: możesz zrobić to, co sugeruje this answer (które powinno być proste do przeniesienia do Pythona). Chociaż sugestie w komentarzach brzmią jak lepsza droga.

+0

oto [Jak przekierować stdout na poziomie C w Pythonie] (http://stackoverflow.com/a/22434262/4279) – jfs

0

Użyłem następujący hack, przed importem readline

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

problem pojawia się również z ' xterm-256color' –

+0

, ale ustawienie 'os.environ ['TERM'] = ''', a następnie importowanie 'readline', a następnie przywracanie' os.environ ['TERM'] 'z powrotem do tego, co było przed, unika drukowania sekwencji ucieczki (nie jestem pewien co do innej funkcjonalności' readline' chociaż ...) –

1

oto co używam (co prawda na podstawie odpowiedzi @jypeter „s), wyczyszczenie zmienną środowiskową TERM tylko jeśli wyjście nie przejdź do tty (np. jest przekierowywany do pliku):

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 
Powiązane problemy