Как очистить вывод функции печати?
Как заставить функцию печати 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...')