Вопрос

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

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

Это было полезно?

Решение

import sys
sys.stdout.flush()

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

Рекомендации

Питон 2

Питон 3

Другие советы

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

  

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

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

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

  

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

     

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

     

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

     

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

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

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

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

Питон 3.3+

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

print('foo', flush=True) 

Python 2 (или < 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() после печати, например, с помощью оператора печати в 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() и объектах файлов (для строки в sys.stdin), на которую эта опция не влияет.Чтобы обойти эту проблему, вам нужно будет использовать file.readline() внутри while 1:петля.

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

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

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

$ export PYTHONUNBUFFERED=TRUE

или Windows:

C:\SET PYTHONUNBUFFERED=TRUE

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

PYTHONНЕБУФЕРИРОВАННЫЙ

Если для этого параметра задана непустая строка, это эквивалентно указанию опции -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.

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

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

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

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

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

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

print("Visiting toilet", flush=True)
<Ч>

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

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

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)

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

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

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

ИЛИ

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

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

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

заставляет его работать нормально.

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

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

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

'''To write to screen in real-time'''
message = lambda x: print(x, flush=True, end="")
message('I am flushing out now...')
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top