Как очистить вывод функции печати? - PullRequest
1023 голосов
/ 23 октября 2008

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

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

Ответы [ 14 ]

1210 голосов
/ 23 октября 2008
import sys
sys.stdout.flush()

print по умолчанию печатает в sys.stdout.

Ссылки

Python 2

Python 3

322 голосов
/ 23 октября 2008

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

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

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

296 голосов
/ 18 апреля 2014

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

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

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

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

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

148 голосов
/ 18 февраля 2016

Как очистить вывод печати 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 (или <3.3) </h2> Они не перенесли аргумент 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() после печати, например, с оператором печати в 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.
67 голосов
/ 27 февраля 2012

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

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

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

51 голосов
/ 21 октября 2015

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

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

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

print("Visiting toilet", flush=True)

Запись документов Python

35 голосов
/ 23 октября 2008

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

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)

... Теперь все ваши print вызовы (которые используют sys.stdout неявно) будут автоматически flush ed.

19 голосов
/ 12 апреля 2009

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

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

OR

sys.stdout = open('out.log', 'a', 0)
15 голосов
/ 12 декабря 2011
import sys
print 'This will be output immediately.'
sys.stdout.flush()
13 голосов
/ 14 ноября 2008

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

#!/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):

делает это просто отлично.

...