Python не работает в небуферизованном режиме

У меня проблема с питоном. Я использовал Python 2.7.13 и Python 3.6.0 на Red Hat Enterprise Linux Server версии 7.1 (Maipo). Чтобы контролировать вывод процессов, я хочу использовать tail -f, чтобы вживую взглянуть на STDOUT и STDERR. Ключевое слово здесь - небуферизованный вывод. Многие предложения в Интернете говорят об использовании python -u ... или переменной окружения PYTHONUNBUFFERED, например PYTHONUNBUFFERED=1 python ... или stdbuf -e0 -o0 python .... Тем не менее, следующий тестовый сценарий не вызывает никаких трудностей.

import sys
import time
while(True):
   print("Test String")
   time.sleep(1);

Для всех разных команд у меня всегда есть буферизованный вывод. Даже если я хочу использовать STDERR. Он по-прежнему находится в буфере, что меня очень смущает, потому что STDERR по умолчанию не должен быть буферизован. Использование sys.stdout.flush() или sys.stderr.flush() также не работает. При использовании flush=True внутри print() он работает как задумано.

Я ищу решение, в котором нет необходимости редактировать код, потому что я не могу редактировать все программы, чтобы получить небуферизованный и немедленно очистить вывод. Как я могу этого добиться?

Жду ваших ответов!

С наилучшими пожеланиями!


person fwillo    schedule 07.11.2017    source источник
comment
Что вы ожидаете от вашего тестового сценария?   -  person Nils Werner    schedule 07.11.2017
comment
Вы можете переопределить print(flush=True) функцию.   -  person Elis Byberi    schedule 07.11.2017
comment
Итак, в моем исходном скрипте есть некоторые результаты глубокого обучения и шагов нейронной сети, которые я хочу отслеживать. В моем тестовом сценарии я сузил его до фиктивного вывода, чтобы увидеть, не буферизован ли вывод. @ElisByberi для этого мне нужно отредактировать код. Некоторые программы настолько огромны, что их редактирование закончится беспорядком ... Я ищу что-нибудь python -u или PYTHONUNBUFFERED вместо того, чтобы они работали ... Я даже не знаю, почему они не работают так, как рекламируется.   -  person fwillo    schedule 07.11.2017
comment
Опять таки. Что вы хотите, чтобы print("Test String") сделал то, чего нет? независимо от того, буферизован он или нет, результат будет одинаковым.   -  person Nils Werner    schedule 08.11.2017
comment
Как описано в моем исходном сообщении, я хочу вызвать в фоновом режиме скрипт Python, который создает выходные данные stdout и stderr в файлах. Время от времени я хочу контролировать вывод, созданный этим скриптом, через print с tail, чтобы увидеть, как идет прогресс. print("Test String") - это просто фиктивный сценарий, с помощью которого я хочу это проверить. До сих пор stdout и stderr, а также print создавали буферизованный вывод при перенаправлении их в файл. Поэтому трудно отслеживать мои журналы с помощью tailf, потому что я получаю новый вывод каждые 4-6 часов.   -  person fwillo    schedule 09.11.2017


Ответы (1)


Вы можете переопределить print() функцию в Python 3. Таким образом, вам не нужно будет изменять каждую print() функцию в ваших скриптах.

import builtins


def print(*args):
    builtins.print(*args, sep=' ', end='\n', file=None, flush=True)


print(
    'hello', 'world',
    'I have overrode print() function!',
    1,  # integer
    [1, 2],  # list
    {1, 2},  # set
    (1, 2),  # tuple
    {1: 2}  # dict
)

напечатает:

hello world I have overrode print() function! 1 [1, 2] {1, 2} (1, 2) {1: 2}
person Elis Byberi    schedule 07.11.2017
comment
Спасибо за ваше предложение. К сожалению, результат ('Test String',). Я был бы счастлив, когда python -u или PYTHONUNBUFFERED будет работать, как рекламируется ... вы знаете, если я что-то пропустил в отношении тех опций? - person fwillo; 08.11.2017
comment
@TheOrangeman Если честно, код не тестировал. Я поместил это только в качестве примера. Теперь все работает как положено. Спасибо, что сообщили об этом. - person Elis Byberi; 08.11.2017
comment
@TheOrangeman Попробуйте эту команду: python -e PYTHONUNBUFFERED=0 yourscript.py - person Elis Byberi; 08.11.2017
comment
Привет, Элис, спасибо за исправление. Как вы сказали, встроенная функция теперь работает так, как вы рекламируете. При попытке python -e обе мои установки Python говорят, что параметр -e является неизвестным параметром :( - person fwillo; 09.11.2017
comment
@TheOrangeman В python --help перечислены все параметры и аргументы (и соответствующие переменные среды). Это заглавная буква E. Это сработает: python -E PYTHONUNBUFFERED=0 yourscript.py - person Elis Byberi; 09.11.2017
comment
Тоже не работает. Документация сообщает мне об этом -E Ignore all PYTHON* environment variables, e.g. PYTHONPATH and PYTHONHOME, that might be set. Как ни странно PYTHONUNBUFFERED=1 python [...] сейчас работает ... Я трижды проверил написание переменной окружения. Я не могу это объяснить и чувствую себя совершенно глупо из-за того, что не торопился. Спасибо за ваши усилия, @Elias Byberi. - person fwillo; 10.11.2017
comment
@ElisByberi отменяет ли эта функция даже печать внутри пакетов? - person Leonardo Rick; 13.02.2021
comment
@LeonardoRick Вы можете переопределить функцию только в скрипте, затем вы можете импортировать этот скрипт в другие скрипты. Например. Вы переопределяете функцию print() в скрипте custom.py, и где бы вы ни импортировали custom.py, функция print() будет переопределена. - person Elis Byberi; 13.02.2021
comment
@ElisByberi Проблема в том, что печать выполняется внутри библиотеки зависимостей моего проекта. Таким образом, я не могу переопределить этот метод print, поэтому ваше решение не работает для меня - person Leonardo Rick; 13.02.2021
comment
@LeonardoRick Мне не совсем понятно, что вы пытаетесь сказать. - person Elis Byberi; 13.02.2021
comment
@ElisByberi Я использую библиотеку (пирограмму), которая сама выводит отпечаток. Этот отпечаток не будет отменен, если я просто переопределю функцию на моем main.py - person Leonardo Rick; 13.02.2021
comment
@LeonardoRick Я подчеркиваю, что Вы можете переопределить функцию только в скрипте. Например. Если вы переопределите функцию print() в скрипте main.py, она больше нигде не переопределит эту функцию. - person Elis Byberi; 13.02.2021