source

출력 버퍼링 사용 안 함

factcode 2022. 10. 23. 09:57
반응형

출력 버퍼링 사용 안 함

Python의이 하게 되어 ?sys.stdout

긍정적인 답변일 경우 이를 비활성화할 수 있는 방법은 무엇입니까?

지금까지의 제안:

  1. 하다를 사용하세요.-u
  2. sys.stdout를 쓸 때마다 가 도는
  3. ★★PYTHONUNBUFFEREDenv var
  4. sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

in in in in in in in in in in in에 글로벌 를 설정하는 다른 방법이 요?sys/sys.stdout행행 중중 ?? ?? ???

메일링 리스트의 Magnus Lycka로부터의 회답:

python을 사용하여 을 건너뛸 수 .python -u (오류)#!/usr/bin/env python -uPYTONUNBUFFERED라고 합니다.

또한 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)

Credits: Python 메일 목록 어딘가에 있는 "Sebastian"입니다.

네.

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

또는 쓰기마다 sys.stdout에서 .flush()를 호출할 수도 있습니다(또는 자동으로 이 작업을 수행하는 개체로 랩핑할 수도 있습니다).

이건 크리스토방 D에 관한 거야Sousa의 대답은 맞혔는데 아직 코멘트는 못 했어요.

「 」의 flushPython 3의 키워드 인수는 항상 버퍼되지 않은 출력을 유지하기 위해 다음과 같습니다.

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

후 는 항상 단, 출력은 ).flush=False지정됩니다).

하는 때문에 은 부분적으로만 합니다.하지만 내 생각엔print는, 에 하는 가장 입니다.stdout/stderrpython으로 표기되어 있기 때문에, 이 2행은 대부분의 사용 사례를 커버하고 있습니다.

에 주의해 쓸 때 '모듈을 쓸 때'가 가 되지 수 있습니다.모듈을 쓸 때는sys.stdout.

Python 2는 다음 기능을 제공하지 않습니다.flushPython 3 의 Python 할 수 .printhttps://stackoverflow.com/a/27991478/3734258 에서 설명한 바와 같이 기능합니다.

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()은 idempotent가 아니며 여러 콜을 호출하면 다음과 같은 오류가 발생합니다.

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에 추가하는 것은 그다지 좋은 방법이 아닙니다.이는 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)

네, 디폴트로 유효하게 되어 있습니다.python을 호출할 때 명령줄의 -u 옵션을 사용하여 비활성화할 수 있습니다.

Python 3 에서는, 인쇄 기능을 monkey-movel로 해, 항상 flush=True:

_orig_print = print

def print(*args, **kwargs):
    _orig_print(*args, flush=True, **kwargs)

와 같이 를 flash flash를 할 수 .functools.partial:

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

Python을 stdbuf 유틸리티로 실행할 수도 있습니다.

stdbuf -oL python <script>

버퍼링되지 않은 파일을 생성하여 이 파일을 sys.stdout에 할당할 수 있습니다.

import sys 
myFile= open( "a.log", "w", 0 ) 
sys.stdout= myFile

시스템에서 제공하는 stdout은 OS에 의해 python 프로그램에 제공되므로 마법처럼 변경할 수 없습니다.

fcntl을 사용하여 파일 플래그를 즉시 변경할 수도 있습니다.

fl = fcntl.fcntl(fd.fileno(), fcntl.F_GETFL)
fl |= os.O_SYNC # or os.O_DSYNC (if you don't care the file timestamp updates)
fcntl.fcntl(fd.fileno(), fcntl.F_SETFL, fl)

재정의만 가능합니다. write의 of의 sys.stdout「」라고 하는 것.flush권장되는 방법의 실장은 다음과 같습니다.

def write_flush(args, w=stdout.write):
    w(args)
    stdout.flush()

'''w는 원래대로 된다.write메서드 레퍼런스그 후 write_flush의 「원래의」입니다.원본은write덮어쓸 수 있습니다.

stdout.write = write_flush

에서는 '다 하다'라고 가정하고 있습니다.stdout는 이 으로 Import합니다.from sys import stdout.

을 얻는 중 는 " "를 사용하는 입니다.sys.stderrsys.stdout '콜'을 걸 수도 있습니다.sys.stdout.flush()이치노

다음의 조작을 실시하면, 인쇄되는 모든 것을 간단하게 리다이렉트 할 수 있습니다.

import sys; sys.stdout = sys.stderr
print "Hello World!"

특정 리다이렉트 할 도 있습니다.print★★★★★★★★

print >>sys.stderr, "Hello World!"

stdout을 리셋하려면 다음 작업을 수행합니다.

sys.stdout = sys.__stdout__

크래시 없이 동작하는 바리안트(적어도 win32; python 2.7, ipython 0.12) 이후 호출(복수):

def DisOutBuffering():
    if sys.stdout.name == '<stdout>':
        sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

    if sys.stderr.name == '<stderr>':
        sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 0)

(댓글을 달았는데 왠지 모르게 없어졌어요.다시 말씀드리지만:)

  1. CPython(최소한 Linux의 경우)은 출력 위치에 따라 동작이 다릅니다. tty 뒤에 .\n'
    "/"/""를 사용할 수 .flush()위의 -u 옵션 중 하나를 선택합니다.

  2. 출력 버퍼링과 약간 관련이 있습니다.
    , 「」를 하는 경우.

    for line in sys.stdin:

다음으로 CPython에서의 실장에서는 잠시 입력을 수집한 후 다수의 입력 회선에 대해 루프 본문을 실행합니다.스크립트가 각 입력 행에 대해 출력을 쓰려고 할 경우 출력 버퍼링처럼 보일 수 있지만 실제로는 배치되어 있기 때문에 이 스크립트의 출력 버퍼링은 없습니다.flush()기술 등이 도움이 됩니다.흥미롭게도, 당신은 이런 행동을 하지 않습니다.이 문제를 피하기 위해

while True: line=sys.stdin.readline()

언급URL : https://stackoverflow.com/questions/107705/disable-output-buffering

반응형