Jak opróżnić wydruk Pythona?
Proponuję pięć sposobów:
- W Pythonie 3 wywołaj
print(..., flush=True)
(argument flush nie jest dostępny w funkcji drukowania Pythona 2 i nie ma analogii dla instrukcji print).
- Wywołaj
file.flush()
plik wyjściowy (możemy w tym celu owinąć funkcję drukowania Pythona 2), na przykład:sys.stdout
- zastosuj to do każdego wywołania funkcji drukowania w module z funkcją częściową,
print = partial(print, flush=True)
zastosowaną do modułu globalnie.
- zastosuj to do procesu za pomocą flagi (
-u
) przekazanej do polecenia interpretera
- zastosuj to do każdego procesu Pythona w swoim środowisku za pomocą
PYTHONUNBUFFERED=TRUE
(i odznacz zmienną, aby to cofnąć).
Python 3.3+
Używając Pythona w wersji 3.3 lub nowszej, możesz po prostu podać flush=True
jako słowo kluczowe argument print
funkcji:
print('foo', flush=True)
Python 2 (lub <3.3)
Nie przeniosły flush
argumentu do Pythona 2.7. Jeśli więc używasz języka Python 2 (lub mniejszego niż 3.3) i chcesz kodu zgodnego zarówno z 2, jak i 3, proponuję następujący kod zgodności. (Uwaga: __future__
import musi znajdować się w / bardzo „u góry modułu ”):
from __future__ import print_function
import sys
if sys.version_info[:2] < (3, 3):
old_print = print
def print(*args, **kwargs):
flush = kwargs.pop('flush', False)
old_print(*args, **kwargs)
if flush:
file = kwargs.get('file', sys.stdout)
# Why might file=None? IDK, but it works for print(i, file=None)
file.flush() if file is not None else sys.stdout.flush()
Powyższy kod zgodności obejmie większość zastosowań, ale w celu dokładniejszego zapoznania się z six
modułem .
Alternatywnie możesz po prostu zadzwonić file.flush()
po wydrukowaniu, na przykład za pomocą instrukcji print w Pythonie 2:
import sys
print 'delayed output'
sys.stdout.flush()
Zmiana wartości domyślnej w jednym module na flush=True
Możesz zmienić wartość domyślną dla funkcji drukowania, używając funools.partial w globalnym zakresie modułu:
import functools
print = functools.partial(print, flush=True)
jeśli spojrzysz na naszą nową funkcję częściową, przynajmniej w Pythonie 3:
>>> print = functools.partial(print, flush=True)
>>> print
functools.partial(<built-in function print>, flush=True)
Widzimy, że działa tak jak normalnie:
>>> print('foo')
foo
I możemy faktycznie zastąpić nową wartość domyślną:
>>> print('foo', flush=False)
foo
Uwaga: zmienia to tylko bieżący zakres globalny, ponieważ nazwa wydruku w bieżącym zakresie globalnym przesłania wbudowaną print
funkcję (lub nie odwołuje się do funkcji zgodności, jeśli używa się jej w Pythonie 2, w tym bieżącym zakresie globalnym).
Jeśli chcesz to zrobić wewnątrz funkcji zamiast w globalnym zasięgu modułu, powinieneś nadać jej inną nazwę, np .:
def foo():
printf = functools.partial(print, flush=True)
printf('print stuff like this')
Jeśli deklarujesz, że jest funkcją globalną w funkcji, zmieniasz ją w globalnej przestrzeni nazw modułu, więc powinieneś po prostu umieścić ją w globalnej przestrzeni nazw, chyba że to konkretne zachowanie jest dokładnie tym, czego chcesz.
Zmiana wartości domyślnej dla procesu
Myślę, że najlepszą opcją jest użycie -u
flagi, aby uzyskać niebuforowane wyjście.
$ python -u script.py
lub
$ python -um package.module
Z dokumentów :
Zmuś stdin, stdout i stderr do całkowitego niebuforowania. W systemach, w których ma to znaczenie, ustaw także stdin, stdout i stderr w trybie binarnym.
Zauważ, że w plikach.readlines () i obiektach plików (dla linii w sys.stdin) istnieje wewnętrzne buforowanie, na które ta opcja nie ma wpływu. Aby obejść ten problem, należy użyć file.readline () wewnątrz pętli while 1:.
Zmienianie wartości domyślnej dla środowiska operacyjnego powłoki
Możesz uzyskać takie zachowanie dla wszystkich procesów Pythona w środowisku lub środowiskach dziedziczących po środowisku, jeśli ustawisz zmienną środowiskową na niepusty ciąg:
np. w systemie Linux lub OSX:
$ export PYTHONUNBUFFERED=TRUE
lub Windows:
C:\SET PYTHONUNBUFFERED=TRUE
z dokumentów :
PYTHONUNBUFFERED
Jeśli ustawiono niepusty ciąg znaków, jest to równoważne z określeniem opcji -u.
Uzupełnienie
Oto pomoc na temat funkcji drukowania z Python 2.7.12 - zauważ, że nie ma flush
argumentu:
>>> from __future__ import print_function
>>> help(print)
print(...)
print(value, ..., sep=' ', end='\n', file=sys.stdout)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
__future__
wersja nie zawiera,flush
ponieważ „argument Python został dodany w Pythonie 3.3 (po tym, jak print () został przeniesiony do wersji 2.7 za pomocą przyszłego importu)” bugs.python.org/issue28458Również zgodnie z sugestią na tym blogu można ponownie otworzyć
sys.stdout
w trybie niebuforowanym:Każda
stdout.write
iprint
operacja zostanie automatycznie spłukuje później.źródło
UnsupportedOperation: IOStream has no fileno.
W Pythonie 3.x
print()
funkcja została rozszerzona:Możesz po prostu zrobić:
Python Docs Entry
źródło
Korzystanie z
-u
przełącznika wiersza polecenia działa, ale jest nieco niezdarne. Oznaczałoby to, że program potencjalnie zachowywałby się niepoprawnie, gdyby użytkownik wywołał skrypt bez-u
opcji. Zwykle używam niestandardowegostdout
, takiego jak to:... Teraz wszystkie twoje
print
rozmowy (które będą używanesys.stdout
niejawnie) zostaną automatycznieflush
edytowane.źródło
def __getattr__(self,name): return object.__getattribute__(self.f, name)
Dlaczego nie spróbować użyć niebuforowanego pliku?
LUB
źródło
Pomysł Dana nie działa:
Wynik:
Uważam, że problem polega na tym, że dziedziczy on po klasie plików, co w rzeczywistości nie jest konieczne. Według dokumentacji dla sys.stdout:
tak się zmienia
do
sprawia, że działa dobrze.
źródło
Oto moja wersja, która zawiera również writelines () i fileno ():
źródło
file
, pojawia się błąd. Nie mafile
klasy.W Pythonie 3 możesz zastąpić funkcję drukowania domyślnie ustawioną na
flush = True
źródło
Tak zrobiłem w Pythonie 3.4:
źródło
Najpierw starałem się zrozumieć, jak działa opcja koloru. Chciałem zrobić „ładowanie ekranu” i oto rozwiązanie, które znalazłem:
Pierwszy wiersz opróżnia poprzedni wydruk, a drugi wiersz drukuje nową zaktualizowaną wiadomość. Nie wiem, czy istnieje tutaj składnia jednowierszowa.
źródło