2016-07-10 2 views
0
#! python3 
from contextlib import redirect_stderr 
import io 

f = io.StringIO() 
with redirect_stderr(f): 
    # simulates an error 
    erd 

Как видно выше, я использовал функцию redirect_stderr перенаправить поток ошибок на StringIO объекта. Тем не менее, он не работает, так как сообщение об ошибке не печатается в командной строке:redirect_stderr не работает (Python 3.5)

Traceback (most recent call last): 
    File "C:\Users\max\testerr.py", line 8, in <module> 
    erd 
NameError: name 'erd' is not defined 

Я испытал это на Python 3.5.1 64 битной и 64 битной 3.5.2 с теми же результатами.

A similar issue in this thread

Я также пытался писать ошибку в файл, как описано в связанном потоке, но файл пуст после выполнения сценария.

+0

Я думаю, что перед инициализацией erd открывается. Можете ли вы рассмотреть возможность определения переменной или проверить, передано ли она в вызове функции и повторной попытке? –

+0

'sys.stderr = io.StringIO()', вы должны знать, что ошибка все равно будет поднята, поэтому сохранение в панели объектов io, которую вы перехватываете, кажется излишним –

ответ

2

Вам необходимо написать stderr, это не инструмент для исключения исключений.

>>> from contextlib import redirect_stderr 
>>> import io 
>>> f = io.StringIO() 
>>> import sys 
>>> with redirect_stderr(f): 
... print('Hello', file=sys.stderr) 
... 
>>> f.seek(0) 
0 
>>> f.read() 
'Hello\n' 

Чтобы поймать исключения, вам нужно сделать еще одну работу. Вы можете использовать библиотеку регистрации (внешний) или написать свой собственный обработчик исключений, а затем использовать для этого свой собственный вывод.

Вот что-то быстро, который использует экземпляр регистратора, чтобы помочь написать в поток:

log = logging.getLogger('TEST') 
log.addHandler(logging.StreamHandler(stream=f)) 

def exception_handler(exc_type, exc_value, exc_traceback): 
    if issubclass(exc_type, KeyboardInterrupt): 
     # Let the system handle things like CTRL+C 
     sys.__excepthook__(*args) 
    log.error('Exception: ', exc_info=(exc_type, exc_value, exc_traceback)) 

sys.excepthook = exception_handler 
raise RuntimeError('foo') 

Здесь f тот же StringIO экземпляр сверху. После того, как вы запустите этот код, вы не увидите никакой трассировки на консоли, но он будет сохранен в объекте потока:

>>> f.seek(0) 
0 
>>> print(f.read()) 
Hello 
Exception: 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
RuntimeError: foo 
+0

Спасибо за разъяснение. Я предположил, что 'redirect_stderr' может позволить мне скрывать вывод stderr неявно. – iridescent

 Смежные вопросы

  • Нет связанных вопросов^_^