Как очистить вывод функции печати?

Как заставить функцию печати Python выводить на экран?

Это не дубликат Отключить буферизацию вывода - связанный вопрос пытается получить небуферизованный вывод, в то время как это более общий. Лучшие ответы в этом вопросе слишком сильны или задействованы для этого (они не являются хорошими ответами на это), и этот вопрос можно найти в Google относительным новичком.

Ответы

Ответ 1

В Python 3 print может принимать необязательный аргумент flush

print("Hello world!", flush=True)

На Python 2 вам придется делать

import sys
sys.stdout.flush()

после звонка print. По умолчанию print печатает в sys.stdout (подробнее о объектах файлов см. документацию).

Ответ 2

Запуск python -h, я вижу вариант командной строки:

-u: небуферизованный двоичный stdout и stderr; также PYTHONUNBUFFERED = x          см. справочную страницу для подробной информации о внутренней буферизации, относящейся к '-u'

Вот соответствующий документ.

Ответ 3

С Python 3.3 вы можете принудительно отключить обычную функцию print() без использования sys.stdout.flush(); просто установите для аргумента ключевого слова "flush" значение true. Из документации:

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

Печать объектов в файл потока, разделенных sep и последующим завершением. sep, end и file, если они есть, должны быть указаны как аргументы ключевых слов.

Все аргументы без ключевого слова преобразуются в строки, такие как str(), и записываются в поток, разделенные sep и затем заканчиваются. Оба sep и end должны быть строками; они также могут быть None, что означает использование значений по умолчанию. Если объекты не заданы, print() будет просто писать конец.

Аргумент файла должен быть объектом с методом write (string); если он отсутствует или None, будет использоваться sys.stdout. Буферизуется ли вывод, как правило, определяется файлом, но если аргумент ключевого слова flush равен true, поток принудительно очищается.

Ответ 4

  Как очистить вывод печати Python?

Я предлагаю пять способов сделать это:

  • В Python 3 вызовите print(..., flush=True) (аргумент flush недоступен в функции печати Python 2, и аналога для оператора print нет).
  • Вызовите file.flush() для выходного файла (для этого мы можем обернуть функцию печати Python 2), например, sys.stdout
  • применить это к каждому вызову функции печати в модуле с частичной функцией,
    print = partial(print, flush=True) применяется к модулю global.
  • применить это к процессу с помощью флага (-u), переданного команде интерпретатора
  • примените это к каждому процессу Python в вашей среде с помощью PYTHONUNBUFFERED=TRUE (и отмените переменную, чтобы отменить это).

Python 3. 3+

Используя Python 3.3 или выше, вы можете просто предоставить flush=True в качестве аргумента ключевого слова для функции print:

print('foo', flush=True) 

Python 2 (или & lt; 3.3)

Они не перенесли аргумент flush в Python 2.7. Поэтому, если вы используете Python 2 (или менее 3.3) и хотите код, совместимый как с 2, так и с 3, могу ли я предложить следующий код совместимости. (Обратите внимание, что импорт __future__ должен находиться в/очень "около верхней части вашего модуля"):

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()

Приведенный выше код совместимости будет охватывать большинство областей применения, но для более тщательного рассмотрения см. модуль six.

В качестве альтернативы вы можете просто вызвать file.flush() после печати, например, с помощью оператора print в Python 2:

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

Изменение значения по умолчанию в одном модуле на flush=True

Вы можете изменить значение по умолчанию для функции печати, используя functools.partial в глобальной области видимости модуля:

import functools
print = functools.partial(print, flush=True)

если вы посмотрите на нашу новую частичную функцию, по крайней мере, в Python 3:

>>> print = functools.partial(print, flush=True)
>>> print
functools.partial(<built-in function print>, flush=True)

Мы видим, что все работает как обычно:

>>> print('foo')
foo

И мы можем переопределить новое значение по умолчанию:

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

Обратите внимание, это только изменяет текущую глобальную область, потому что имя печати в текущей глобальной области будет затенять встроенную функцию print (или не будет ссылаться на функцию совместимости, если она используется в Python 2, в этой текущей глобальной области)).

Если вы хотите сделать это внутри функции, а не в глобальной области видимости модуля, вам следует дать ему другое имя, например:

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

Если вы объявляете его глобальным в функции, вы изменяете его в глобальном пространстве имен модуля, поэтому вам просто нужно поместить его в глобальное пространство имен, если только это конкретное поведение не является именно тем, что вам нужно.

Изменение значения по умолчанию для процесса

Я думаю, что лучшим вариантом здесь является использование флага -u для получения небуферизованного вывода.

$ python -u script.py

или

$ python -um package.module

Из документов:

Заставьте stdin, stdout и stderr быть полностью небуферизованными. В системах, где это важно, также установите stdin, stdout и stderr в двоичном режиме.

Обратите внимание, что в file.readlines() и File Objects (для строки в sys.stdin) есть внутренняя буферизация, на которую не влияет эта опция. Чтобы обойти это, вам нужно использовать file.readline() внутри цикла while 1:.

Изменение значения по умолчанию для операционной среды оболочки

Вы можете получить это поведение для всех процессов Python в среде или средах, которые наследуются от среды, если для переменной среды задать непустую строку:

например, в Linux или OSX:

$ export PYTHONUNBUFFERED=TRUE

или Windows:

C:\SET PYTHONUNBUFFERED=TRUE

из документов:

PYTHONUNBUFFERED

Если для этого параметра задана непустая строка, это эквивалентно указанию параметра -u.


Добавление

Вот справка по функции печати из Python 2.7.12 - обратите внимание, что аргумента flush нет:

>>> 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.

Ответ 5

Также, как предлагается в этом блоге, можно повторно открыть sys.stdout в небуферизованном режиме:

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

Каждая операция stdout.write и print будет автоматически очищаться после этого.

Ответ 6

В Python 3.x функция print() была расширена:

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

Итак, вы можете просто сделать:

print("Visiting toilet", flush=True)

Python Docs Entry

Ответ 7

Использование -u командной строки -u работает, но это немного неуклюже. Это будет означать, что программа потенциально может вести себя некорректно, если пользователь -u сценарий без опции -u. Я обычно использую пользовательский стандартный stdout, например так:

class flushfile:
  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 вызовы (которые используют sys.stdout неявно), будут автоматически flush ред.

Ответ 8

Почему бы не попробовать использовать небуферизованный файл?

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

ИЛИ

sys.stdout = open('out.log', 'a', 0)

Ответ 9

import sys
print 'This will be output immediately.'
sys.stdout.flush()

Ответ 10

Идея Дэн не совсем работает:

#!/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"

Результат:

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

Я считаю, что проблема в том, что он наследует от класса файлов, что на самом деле не является необходимым. Согласно документам для sys.stdout:

stdout и stderr не должны быть встроены файловые объекты: любой объект является приемлемым если у него есть метод write() который принимает строковый аргумент.

поэтому изменение

class flushfile(file):

к

class flushfile(object):

делает работу просто прекрасной.

Ответ 11

Вот моя версия, которая также предоставляет writelines() и 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()

Ответ 12

Решительно настроенный Дэн! Для python3 выполните:

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)

Ответ 13

В Python 3 вы можете перезаписать функцию печати с настройкой по умолчанию на flush = True

def print(*objects, sep=' ', end='\n', file=sys.stdout, flush=True):
    __builtins__.print(*objects, sep=sep, end=end, file=file, flush=flush)

Ответ 14

Я сделал это в Python 3.4:

'''To write to screen in real-time'''
message = lambda x: print(x, flush=True, end="")
message('I am flushing out now...')