[python] 출력 버퍼링 비활성화

파이썬의 인터프리터에서 출력 버퍼링이 기본적으로 활성화되어 sys.stdout있습니까?

답변이 긍정적이면 어떻게 비활성화 할 수 있습니까?

지금까지 제안 :

  1. 사용 -u명령 줄 스위치를
  2. sys.stdout모든 쓰기 후에 플러시되는 객체를 감싸십시오 .
  3. PYTHONUNBUFFERED환경 변수 설정
  4. sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

일부 전역 플래그를 설정하는 다른 방법이 있나요 sys/ sys.stdout실행 중에 프로그램은?



답변

에서 메일 링리스트에 매그너스 Lycka 답변 :

“python -u”(또는 #! / usr / bin / env python -u 등)를 사용하거나 환경 변수 PYTHONUNBUFFERED를 설정하여 전체 파이썬 프로세스에 대한 버퍼링을 건너 뛸 수 있습니다.

sys.stdout을 모든 호출 후에 플러시하는 래퍼와 같은 다른 스트림으로 바꿀 수도 있습니다.

class Unbuffered(object):
   def __init__(self, stream):
       self.stream = stream
   def write(self, data):
       self.stream.write(data)
       self.stream.flush()
   def writelines(self, datas):
       self.stream.writelines(datas)
       self.stream.flush()
   def __getattr__(self, attr):
       return getattr(self.stream, attr)

import sys
sys.stdout = Unbuffered(sys.stdout)
print 'Hello'

답변

인쇄 기능의 출력을 플러시하는 방법에 오히려 대답을하고 싶습니다 . 또는 호출 될 때 버퍼를 플러시하는 Python의 인쇄 함수에서? , 그러나이 내용이 중복 된 것으로 표시되었으므로 (동의하지 않는 내용) 여기에 답변하겠습니다.

Python 3.3부터 print ()는 키워드 인수 “flush”를 지원합니다 ( 문서 참조 ).

print('Hello World!', flush=True)


답변

# reopen stdout file descriptor with write mode
# and 0 as the buffer size (unbuffered)
import io, os, sys
try:
    # Python 3, open as binary, then wrap in a TextIOWrapper with write-through.
    sys.stdout = io.TextIOWrapper(open(sys.stdout.fileno(), 'wb', 0), write_through=True)
    # If flushing on newlines is sufficient, as of 3.7 you can instead just call:
    # sys.stdout.reconfigure(line_buffering=True)
except TypeError:
    # Python 2
    sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

크레딧 : “Sebastian”, 파이썬 메일 링리스트 어딘가에.


답변

그렇습니다.

“-u”스위치를 사용하여 명령 줄에서 비활성화 할 수 있습니다.

또는 모든 쓰기마다 sys.stdout에서 .flush ()를 호출하거나 자동으로 수행하는 객체로 래핑 할 수 있습니다


답변

이것은 Cristóvão D. Sousa의 답변과 관련이 있지만 아직 언급 할 수 없습니다.

버퍼링되지 않은 출력 을 항상 유지 하기 위해 Python 3flush키워드 인수 를 사용하는 간단한 방법 은 다음과 같습니다.

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

그 후 인쇄는 항상 출력을 직접 플러시합니다 (제외됨 flush=False).

(a) 이것은 모든 출력을 리디렉션하지 않으므로 질문에 부분적으로 만 대답한다는 점에 유의하십시오. 그러나 파이썬에서 / 로 print출력을 만드는 가장 일반적인 방법 이라고 생각 합니다. 이 두 줄은 아마도 대부분의 사용 사례를 다룹니다.stdoutstderr

참고 (b)는 정의한 모듈 / 스크립트에서만 작동합니다. 모듈을 작성할 때 좋을 수 있습니다 sys.stdout.

Python 2flush인수를 제공하지 않지만 https://stackoverflow.com/a/27991478/3734258에print 설명 된대로 Python 3 유형 함수를 에뮬레이션 할 수 있습니다 .


답변

def disable_stdout_buffering():
    # Appending to gc.garbage is a way to stop an object from being
    # destroyed.  If the old sys.stdout is ever collected, it will
    # close() stdout, which is not good.
    gc.garbage.append(sys.stdout)
    sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

# Then this will give output in the correct order:
disable_stdout_buffering()
print "hello"
subprocess.call(["echo", "bye"])

이전 sys.stdout을 저장하지 않으면 disable_stdout_buffering ()이 dem 등성이 아니며 여러 호출로 인해 다음과 같은 오류가 발생합니다.

Traceback (most recent call last):
  File "test/buffering.py", line 17, in <module>
    print "hello"
IOError: [Errno 9] Bad file descriptor
close failed: [Errno 9] Bad file descriptor

또 다른 가능성은 다음과 같습니다.

def disable_stdout_buffering():
    fileno = sys.stdout.fileno()
    temp_fd = os.dup(fileno)
    sys.stdout.close()
    os.dup2(temp_fd, fileno)
    os.close(temp_fd)
    sys.stdout = os.fdopen(fileno, "w", 0)

gc.garbage에 추가하는 것은 순환 할 수없는주기가있는 위치에 있으므로 좋은 아이디어가 아닙니다.이를 확인하고 싶을 수도 있습니다.


답변

다음은 Python 2.6, 2.7 및 3.2에서 작동합니다.

import os
import sys
buf_arg = 0
if sys.version_info[0] == 3:
    os.environ['PYTHONUNBUFFERED'] = '1'
    buf_arg = 1
sys.stdout = os.fdopen(sys.stdout.fileno(), 'a+', buf_arg)
sys.stderr = os.fdopen(sys.stderr.fileno(), 'a+', buf_arg)