2013-04-02 2 views
8

Я использую модуль readline с Python 2.7.3 с Fedora 17. У меня нет этой проблемы с Ubuntu 12.10.Модуль Readline Python печатает escape-символ во время импорта

В течение import readline отображается символ возврата.

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

Обычно, когда я получаю неожиданный выход, как это, я обрабатывать его с помощью stdout/stderr редиректа фиктивного дескриптора файла (например, ниже). Но на этот раз этот метод не работает.

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' 

Если запустить этот фрагмент в test.py сценарии, вы увидите, что внутри suppress_output контексте print заявления действительно подавлено, но не бежать символ.

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

Так вот мои два вопроса:

  1. Как это возможно, для этого маскирующим пройти через это?
  2. Как его подавить?
+1

Похоже, модуль хочет изменить состояние терминала с помощью escape-последовательности, но это не сработает. Вы не должны пытаться обойти это, исправьте это. – wRAR

+0

Да, есть обходное решение, основанное на этом http://reinout.vanrees.org/weblog/2009/08/14/readline-invisible-character-hack.html. Но это не отвечало моему первому вопросу :) (и я боялся, что это не очень портативно, но я могу ошибаться). – Alex

+0

Я подозреваю, что ваш терминал и/или terminfo DB вызывают эту проблему. – wRAR

ответ

0

Чтобы ответить на первый вопрос: изменение sys.stdout фактически не влияет на то, что файл stdout's file descriptor is pointing at, но вместо этого только то, что объектный файл высокого уровня Python считает быть стандартный вывод. С другой стороны, изменение sys.stdout влияет на ваш код Python, но не (как правило) любые скомпилированные расширения, которые вы можете использовать (например, модуль readline). Все это относится и к sys.stderr.

Чтобы ответить на второй вопрос: вы можете сделать то, что предлагает this answer (что должно быть простым для порта на Python). Хотя предложения в комментариях звучат как лучший способ пойти.

+0

здесь [как перенаправить stdout на уровне C в Python] (http://stackoverflow.com/a/22434262/4279) – jfs

0

Я использовал следующий хак, перед импортом Readline

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

проблема появляется также с ' xterm-256color' –

+0

, но установив 'os.environ ['TERM'] = ''', затем импортируя 'readline', а затем восстанавливая' os.environment ['TERM'] 'назад к тому, что было до этого, избегает печати escape-последовательности (не уверен в других функциях' readline', хотя ...) –

1

вот что я использую (правда, на основе ответа @jypeter «s), очистка переменной TERM среды, только если выход не перейдите к tty (например, перенаправляется в файл):

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 
Смежные вопросы