인쇄 기능의 출력을 플러시하는 방법은 무엇입니까?


1216

파이썬의 인쇄 기능이 화면에 출력되도록하려면 어떻게해야합니까?

이것은 출력 버퍼링 사용 안함 의 복제본이 아닙니다. 링크 된 질문은 버퍼되지 않은 출력을 시도하는 반면, 이것은 더 일반적입니다. 해당 질문의 상위 답변은 너무 강력하거나 관련이 있으며 (이 답변에는 적합하지 않음)이 질문은 Google에서 관련 초보자가 찾을 수 있습니다.

답변:


1428

Python 3에서는 print선택적 flush인수를 사용할 수 있습니다

print("Hello world!", flush=True)

파이썬 2에서는해야 할 일이 있습니다

import sys
sys.stdout.flush()

전화 후 print. 기본적으로에 print인쇄합니다 sys.stdout( 파일 객체에 대한 자세한 내용은 설명서를 참조하십시오 ).


346

실행 python -h명령 줄 옵션이 표시됩니다 .

-u : 버퍼되지 않은 이진 stdout 및 stderr; 또한 PYTHONUNBUFFERED = x '-u'와 관련된 내부 버퍼링에 대한 자세한 내용은 매뉴얼 페이지를 참조하십시오

관련 문서 는 다음과 같습니다 .


320

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 ()는 단지 end를 쓸 것입니다.

파일 인수는 write (string) 메소드가있는 객체 여야합니다. 존재하지 않거나 없음이면 sys.stdout이 사용됩니다. 출력이 버퍼링되는지 여부는 일반적으로 파일에 의해 결정되지만 flush 키워드 인수가 true이면 스트림이 강제로 플러시됩니다.


197

파이썬 프린트의 출력을 플러시하는 방법?

이 작업을 수행하는 다섯 가지 방법을 제안합니다.

  • Python 3에서 call print(..., flush=True)(플러시 인수는 Python 2의 인쇄 함수에서 사용할 수 없으며 print 문에 대한 아날로그가 없습니다).
  • file.flush()예를 들어, 출력 파일을 호출 하십시오 (파이썬 2의 인쇄 기능을 래핑 할 수 있습니다).sys.stdout

  • print = partial(print, flush=True)모듈 전역에 적용되는 부분 함수를 사용하여 모듈의 모든 인쇄 함수 호출에 이것을 적용하십시오 .
  • -u인터프리터 명령에 전달 된 플래그 ( ) 를 사용하여 프로세스에 적용
  • 이것을 사용하여 환경의 모든 파이썬 프로세스에 적용하십시오 PYTHONUNBUFFERED=TRUE(이를 실행 취소하려면 변수를 설정 해제하십시오).

파이썬 3.3+

Python 3.3 이상을 사용 flush=True하면 print함수에 키워드 인수로 제공 할 수 있습니다 .

print('foo', flush=True) 

파이썬 2 (또는 <3.3)

flush파이썬 2.7로 인수를 백 포트하지 않았으므로 파이썬 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의 print 문 사용).

import sys
print 'delayed output'
sys.stdout.flush()

한 모듈에서 기본값을 다음으로 변경 flush=True

모듈의 전역 범위에서 functools.partial을 사용하여 인쇄 기능의 기본값을 변경할 수 있습니다.

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

적어도 파이썬 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의 행)에 내부 버퍼링이 있습니다. 이 문제를 해결하려면 while 1 : 루프 내에서 file.readline ()을 사용하십시오.

쉘 운영 환경의 기본값 변경

환경 변수를 비어 있지 않은 문자열로 설정하면 환경 또는 환경에서 상속되는 환경의 모든 파이썬 프로세스에 대해이 동작을 얻을 수 있습니다.

예를 들어 Linux 또는 OSX에서 :

$ export PYTHONUNBUFFERED=TRUE

또는 Windows :

C:\SET PYTHONUNBUFFERED=TRUE

로부터 문서 :

피토 논 부퍼

이것이 비어 있지 않은 문자열로 설정되면 -u 옵션을 지정하는 것과 같습니다.


추가

다음은 Python 2.7.12의 print 함수에 대한 도움말입니다. 인수 가 없습니다 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.

낮은 파이썬 버전의 호기심 이주의 경우 : __future__버전은 포함하지 않는다 flush"플러시 인수가 파이썬 3.3 (인쇄 후 () 미래의 가져 오기를 통해 2.7에 백 포트했다)에서 추가되었다"때문에 bugs.python.org/issue28458
올리버

69

또한 이 블로그 에서 제안한 것처럼 sys.stdout버퍼링되지 않은 모드에서 다시 열 수 있습니다 .

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

각각 stdout.writeprint작업은 자동으로 플러시됩니다.


2
파이썬 2.7의 우분투 12.04에서 이것은 나에게 준다UnsupportedOperation: IOStream has no fileno.
drevicko

3
혹시, 파이썬 3이 발견했습니다. 이 코드를 실행할 수는 없습니다!
EKons

나는이 관용구에 혼란스러워합니다. 이 작업을 수행 한 후 파일 이름을 "소유"한다고 생각하는 두 개의 File-like 객체 (원본 sys.stdout 및 새 sys.stdout)가 없습니까? 나쁘지 않나요?
돈 해치

62

Python 3.x에서는 print()기능이 확장되었습니다.

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

그래서 당신은 할 수 있습니다 :

print("Visiting toilet", flush=True)

파이썬 문서 입력


36

-u명령 줄 스위치를 사용하면 작동하지만 약간 어색합니다. 사용자가 -u옵션 없이 스크립트를 호출 한 경우 프로그램이 제대로 작동하지 않을 수 있습니다. 나는 보통 stdout다음과 같이 custom을 사용합니다 :

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.


4
파일에서 상속하지 않고 추가하여 stdout에 위임하는 것이 좋습니다. def __getattr__(self,name): return object.__getattribute__(self.f, name)
3

2
@diedthreetimes의 의견에서 제안한 변경 사항이 없으면 "ValueError : 닫힌 파일에 대한 I / O 작업"이 나타납니다.
blueFast

19

버퍼되지 않은 파일을 사용해보십시오.

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

또는

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

1
그는 버퍼되지 않은 파일을 만들고 싶지 않다. 그는 기존 stdout (콘솔, 터미널 또는 다른 것으로 리디렉션 됨)을 버퍼링하지 않기를 원합니다.
blueFast

13

Dan의 아이디어는 효과가 없습니다.

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

잘 작동합니다.


17
이 댄의 솔루션 @이기 때문에 어떤 투표는 ... (당신은 오히려 댄의 게시물을 언급하지 않고 자신의 솔루션을 복사한다)
gecco

8

다음은 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.4.0에서 테스트되었습니다. 에서 파생 된 다른 버전에서는 file오류가 발생합니다. file수업 이 없습니다 .
Colin D Bennett

6

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)

2
이 답변은 다른 모든 고품질 응답을 감안할 때 약간 가벼워 보입니다. 조금 더 추가하고 싶을 수도 있습니다.
세미콜론 및 덕트 테이프

5

파이썬 3.4에서 다음과 같이했습니다.

'''To write to screen in real-time'''
message = lambda x: print(x, flush=True, end="")
message('I am flushing out now...')

2

나는 플러시 옵션이 어떻게 작동하는지 이해하기 위해 먼저 어려움을 겪었습니다. 나는 '로드 디스플레이'를하고 싶었고 여기에 내가 찾은 해결책이 있습니다.

for i in range(100000):
    print('{:s}\r'.format(''), end='', flush=True)
    print('Loading index: {:d}/100000'.format(i+1), end='')

첫 번째 줄은 이전 인쇄를 비우고 두 번째 줄은 업데이트 된 새 메시지를 인쇄합니다. 한 줄짜리 구문이 여기에 있는지 모르겠습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.