Estou usando uma biblioteca Python que faz algo a um objeto
do_something(my_object)
e muda isso. Enquanto faz isso, ele imprime algumas estatísticas para stdout e eu gostaria de ter uma ideia dessas informações. A solução adequada seria mudar do_something()
para retornar as informações relevantes,
out = do_something(my_object)
mas vai demorar um pouco até que os desenvolvedores do_something()
cheguem a esse problema. Como solução alternativa, pensei em analisar tudodo_something()
grava em stdout.
Como posso capturar a saída stdout entre dois pontos no código, por exemplo,
start_capturing()
do_something(my_object)
out = end_capturing()
?
Respostas:
Experimente este gerenciador de contexto:
Uso:
output
agora é uma lista contendo as linhas impressas pela chamada de função.Uso avançado:
O que pode não ser óbvio é que isso pode ser feito mais de uma vez e os resultados concatenados:
Resultado:
Actualizar : Acrescentaram
redirect_stdout()
paracontextlib
em Python 3,4 (juntamente comredirect_stderr()
). Portanto, você pode usario.StringIO
com isso para obter um resultado semelhante (emboraCapturing
ser uma lista, bem como um gerenciador de contexto, seja indiscutivelmente mais conveniente).fonte
.extend()
para que pudesse ser usado concatenativamente, como você notou. :-)self._stringio.truncate(0)
após aself.extend()
chamada no__exit__()
método para liberar parte da memória mantida pelo_stringio
membro.from io import StringIO
vez da primeira linha no gerenciador de contexto.Em python> = 3.4, contextlib contém um
redirect_stdout
decorador. Ele pode ser usado para responder à sua pergunta da seguinte forma:Dos documentos :
fonte
f = io.StringIO() with redirect_stdout(f): logger = getLogger('test_logger') logger.debug('Test debug message') out = f.getvalue() self.assertEqual(out, 'DEBUG:test_logger:Test debug message')
. Isso me dá um erro:AssertionError: '' != 'Test debug message'
logger.debug
não grava no stdout por padrão. Se você substituir sua chamada de registro por,print()
deverá ver a mensagem.stream_handler = logging.StreamHandler(sys.stdout)
. E adicione esse manipulador ao meu logger. então ele deve gravar em stdout eredirect_stdout
deve capturá-lo, certo?Aqui está uma solução assíncrona usando canais de arquivo.
Exemplo de uso:
fonte