Używam biblioteki Python, która robi coś z obiektem
do_something(my_object)
i zmienia to. Robiąc to, wypisuje statystyki na standardowe wyjście i chciałbym mieć kontrolę nad tymi informacjami. Właściwym rozwiązaniem byłaby zmiana do_something()
i zwrócenie odpowiednich informacji,
out = do_something(my_object)
ale minie trochę czasu, zanim twórcy zabiorą do_something()
się do tego wydania. Aby obejść ten problem, pomyślałem o parsowaniu wszystkiego, co do_something()
zapisuje na standardowe wyjście.
Jak mogę przechwycić wyjście standardowego wyjścia między dwoma punktami w kodzie, np.
start_capturing()
do_something(my_object)
out = end_capturing()
?
Odpowiedzi:
Wypróbuj tego menedżera kontekstu:
Stosowanie:
output
jest teraz listą zawierającą wiersze wypisane przez wywołanie funkcji.Zaawansowane użycie:
Co może nie być oczywiste, to fakt, że można to zrobić więcej niż raz, a wyniki są połączone:
Wynik:
Aktualizacja : Dodali
redirect_stdout()
docontextlib
w Pythonie 3.4 (wraz zredirect_stderr()
). Możesz więc użyćio.StringIO
tego do osiągnięcia podobnego wyniku (chociażCapturing
bycie listą i menedżerem kontekstu jest prawdopodobnie wygodniejsze).źródło
.extend()
zamiast tego użyłem, aby można było go używać łącznie, tak jak zauważyłeś. :-)self._stringio.truncate(0)
poself.extend()
wywołaniu__exit__()
metody, aby zwolnić część pamięci posiadanej przez_stringio
członka.from io import StringIO
zamiast pierwszego wiersza w menedżerze kontekstu.W pythonie> = 3.4, contextlib zawiera
redirect_stdout
dekorator. Można go użyć, aby odpowiedzieć na twoje pytanie w następujący sposób:Z dokumentów :
źródło
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')
. Daje mi błąd:AssertionError: '' != 'Test debug message'
logger.debug
nie zapisuje na standardowe wyjście. Jeśli zamienisz wywołanie dziennika naprint()
, powinieneś zobaczyć komunikat.stream_handler = logging.StreamHandler(sys.stdout)
. I dodaj tę obsługę do mojego rejestratora. więc powinien napisać na stdout iredirect_stdout
powinien to złapać, prawda?Oto rozwiązanie asynchroniczne wykorzystujące potoki plików.
Przykładowe użycie:
źródło