Jak spłukać wyjście funkcji drukowania?

Jak wymusić wyświetlenie funkcji drukowania Pythona na ekranie?

nie jest to duplikat Wyłącz buforowanie wyjścia - połączone pytanie próbuje nie buforować wyjścia, podczas gdy jest to bardziej ogólne. Najlepsze odpowiedzi na to pytanie są zbyt potężne lub zaangażowane w to pytanie (nie są to dobre odpowiedzi na to pytanie), a to pytanie można znaleźć w Google przez względnego nowicjusza.

Author: martineau, 2008-10-23

14 answers

 1083
Author: CesarB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-08 03:38:23

Uruchamiając python -h, widzę opcję wiersza poleceń :

- u: unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x więcej informacji na temat buforowania wewnętrznego można znaleźć na stronie man.]}

Oto odpowiedni dokument .

 295
Author: gimel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-23 18:06:49

Od wersji Pythona 3.3, możesz wymusić funkcję print() do spłukiwania bez potrzeby używania sys.stdout.flush(); po prostu ustaw argument słowa kluczowego "flush" na true. Z dokumentacji :

Print (*objects, sep='', end= '\N', file = sys.stdout, flush=False)

Wypisuje obiekty do pliku stream, oddzielone przez sep, a po nim end. sep, end I file, jeśli są obecne, muszą być podane jako argumenty słów kluczowych.

Wszystkie argumenty nie będące słowami kluczowymi są konwertowane na ciągi takie jak str() robią i zapisują do strumienia, oddzielone przez sep, a następnie end. Zarówno sep, jak i end muszą być ciągami znaków; mogą również być None, co oznacza użycie wartości domyślnych. Jeśli nie podano żadnych obiektów, print() po prostu zapisze koniec.

Argument file musi być obiektem z metodą write( string); jeśli nie występuje lub None, sys.zostanie użyty stdout. to, czy wyjście jest buforowane, zwykle zależy od Pliku, ale jeśli argument słowa kluczowego flush jest prawdziwy, strumień jest wypłukany siłą.

 250
Author: Eugene Sajine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-22 00:32:20

Jak spłukać wyjście Pythona print?

Proponuję pięć sposobów na zrobienie tego:

  • w Pythonie 3 wywołanie print(..., flush=True) (argument flush nie jest dostępny w funkcji print Pythona 2 i nie ma analogii dla instrukcji print).
  • wywołanie file.flush() na pliku wyjściowym( w tym celu możemy zawijać funkcję drukowania Pythona 2), na przykład sys.stdout
  • zastosuj to do każdego wywołania funkcji print w module z funkcją częściową,
    print = partial(print, flush=True) stosowane do modułu global.
  • zastosuj to do procesu z flagą (-u) przekazaną komendzie interpretera
  • zastosuj to do każdego procesu Pythona w swoim środowisku za pomocą PYTHONUNBUFFERED=TRUE (i odłącz zmienną, aby to cofnąć).

Python 3.3 +

Używając Pythona 3.3 lub nowszego, możesz po prostu podać flush=True jako argument słowa kluczowego do funkcji print:

print('foo', flush=True) 

Python 2 (or

Nie przenieśli argumentu flush do Pythona 2.7, więc jeśli używasz Pythona 2 (lub mniej niż 3.3) i chcesz kod, który jest kompatybilny zarówno z 2 i 3, mogę zasugerować następujący kod zgodności. (Zauważ, że __future__ import musi znajdować się w / very " w pobliżu górnej części twojego 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 dla bardziej dokładnego leczenia, zobacz six moduł .

Alternatywnie, możesz po prostu wywołać file.flush() po wydrukowaniu, na przykład, z instrukcją print w Pythonie 2:

import sys
print 'delayed output'
sys.stdout.flush()

Zmiana domyślnej wartości w jednym module na flush=True

Możesz zmienić domyślną funkcję drukowania za pomocą functools.częściowy o globalnym zasięgu 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 jak zwykle:

>>> print('foo')
foo

I możemy faktycznie nadpisać nową wartość domyślną:

>>> print('foo', flush=False)
foo

Zauważ jeszcze raz, że zmienia to tylko bieżący zasięg globalny, ponieważ nazwa wydruku w bieżącym globalnym zasięgu przyćmieje wbudowaną funkcję print (lub usunie funkcję zgodności, jeśli używasz Pythona 2, w bieżącym globalnym zasięgu).

Jeśli chcesz to zrobić wewnątrz funkcji, a nie na globalnym zasięgu modułu, powinieneś nadać mu inną nazwę, np.:]}

def foo():
    printf = functools.partial(print, flush=True)
    printf('print stuff like this')

Jeśli zadeklarujesz ją jako globalną w funkcji, zmienisz ją w globalnej przestrzeni nazw modułu, więc powinieneś umieścić ją w globalnej przestrzeni nazw, chyba że to specyficzne zachowanie dokładnie tego chcesz.

Zmiana domyślnej wartości dla procesu

Myślę, że najlepszą opcją jest użycie znacznika -u, Aby uzyskać niebuforowane dane wyjściowe.

$ python -u script.py

Lub

$ python -um package.module

Z docs :

Wymuś całkowite uwolnienie stdin, stdout i stderr. W systemach, w których ma to znaczenie, umieść również stdin, stdout i stderr w trybie binarnym.

Zauważ, że w pliku występuje wewnętrzne buforowanie.readlines () i File Objects (for linia w sys.stdin), na które ta opcja nie ma wpływu. Aby obejść to, będziesz chciał użyć pliku.readline () wewnątrz pętli while 1: loop.

Zmiana domyślnego środowiska pracy powłoki

Można uzyskać to zachowanie dla wszystkich procesów Pythona w środowisku lub środowisk, które dziedziczą ze środowiska, jeśli ustawisz zmienną środowiskową na nonempty string:

Np. w Linuksie lub OSX:

$ export PYTHONUNBUFFERED=TRUE

Lub Okna:

C:\SET PYTHONUNBUFFERED=TRUE

Z docs :

PYTHONUNBUFFERED

Jeśli jest ustawiony na niepusty łańcuch, jest to równoważne z podaniem opcji-u.


Dodatek

Oto pomoc na funkcji print z Pythona 2.7.12-zauważ, że nie ma Nie flush argument:

>>> 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.
 112
Author: Aaron Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-08 00:43:04

Również zgodnie z sugestią w Ten blog można otworzyć ponownie sys.stdout w trybie unbuffered:

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

Każda operacja stdout.write i print zostanie następnie automatycznie przepłukana.

 65
Author: Antony Hatchkins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-01 16:25:12

Użycie przełącznika linii poleceń -u działa, ale jest trochę niezgrabne. Oznaczałoby to, że program potencjalnie zachowałby się nieprawidłowo, gdyby użytkownik wywołał skrypt bez opcji -u. Zazwyczaj używam niestandardowego stdout, Jak to:

class flushfile(object):
  def __init__(self, f):
    self.f = f

  def write(self, x):
    self.f.write(x)
    self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

... Teraz wszystkie Twoje wywołania print (które używają sys.stdout w domyśle), będą automatycznie flushed.

 31
Author: Dan Lenski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-04 19:51:33

Z Pythonem 3.x rozszerzyli funkcję print():

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

Więc możesz po prostu zrobić:

print("Visiting toilet", flush=True)

Python Docs Entry

 30
Author: Noah Krasser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-30 11:50:10

Dlaczego nie spróbować użyć pliku niebuforowanego?

f = open('xyz.log', 'a', 0)

Lub

sys.stdout = open('out.log', 'a', 0)
 17
Author: Nakilon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-13 07:43:45
import sys
print 'This will be output immediately.'
sys.stdout.flush()
 12
Author: Dynamic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-12 07:51:57

Pomysł dana nie działa:

#!/usr/bin/env python
class flushfile(file):
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

import sys
sys.stdout = flushfile(sys.stdout)

print "foo"

Wynik:

Traceback (most recent call last):
  File "./passpersist.py", line 12, in <module>
    print "foo"
ValueError: I/O operation on closed file

Uważam, że problem polega na tym, że dziedziczy ona z klasy plików, co w rzeczywistości nie jest konieczne. Według dokumentów dla sys.stdout:

Stdout i stderr nie muszą być wbudowane obiekty plików: każdy obiekt jest akceptowalny o ile posiada metodę write() to wymaga argumentu string.

Więc zmiana

class flushfile(file):

Do

class flushfile(object):
Sprawia, że działa dobrze.
 10
Author: Kamil Kisiel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-13 22:22:20

Oto moja wersja, która zawiera również writelines () i fileno ():

class FlushFile(object):
    def __init__(self, fd):
        self.fd = fd

    def write(self, x):
        ret = self.fd.write(x)
        self.fd.flush()
        return ret

    def writelines(self, lines):
        ret = self.writelines(lines)
        self.fd.flush()
        return ret

    def flush(self):
        return self.fd.flush

    def close(self):
        return self.fd.close()

    def fileno(self):
        return self.fd.fileno()
 6
Author: guettli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-21 15:36:58

Loved Dan ' s solution! Dla python3 do:

import io,sys
class flushfile:
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()
sys.stdout = flushfile(sys.stdout)
 5
Author: Jonas Byström,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-15 18:19:42

W Pythonie 3 można nadpisać funkcję print z domyślnym ustawieniem na flush = True

def print(*objects, sep=' ', end='\n', file=sys.stdout, flush=True):
    __builtins__.print(*objects, sep=sep, end=end, file=file, flush=flush)
 2
Author: user263387,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-15 19:13:34

Zrobiłem tak w Pythonie 3.4:

'''To write to screen in real-time'''
message = lambda x: print(x, flush=True, end="")
message('I am flushing out now...')
 2
Author: kmario23,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-15 15:22:01