Python의 교차 플랫폼 / dev / null


85

다음 코드를 사용하여 Linux / OSX에서 기본적으로 stderr에 쓰는 제어하지 않는 Python 라이브러리에 대한 stderr을 숨기고 있습니다.

f = open("/dev/null","w")
zookeeper.set_log_stream(f)

/ dev / null에 대한 쉬운 크로스 플랫폼 대안이 있습니까? 장기 실행 프로세스이므로 이상적으로는 메모리를 소비하지 않습니다.



8
@msw : 그렇게 생각하지 않습니다. Python에는이 문제를 처리 할 수있는 더 많은 방법이 있습니다.
Andrew Aylett

답변:



47
class Devnull(object):
    def write(self, *_): pass

zookeeper.set_log_stream(Devnull())

os.devnull물론 여는 것도 괜찮지 만 이런 식으로 모든 출력 작업이 "진행 중"으로 발생합니다. 즉, OS와 그 반대로 컨텍스트 전환이없고 버퍼링도 없습니다 (일부 버퍼링은 일반적으로에서 사용됨 open). 더 적은 메모리 소비.


6
os.devnull을 사용하면 오버 헤드가 발생할 수 있음을 이해합니다. 그러나 만약 하나가 당신의 객체를 사용한다면 사육사 객체가 writelog_stream 파일 객체의 다른 메소드를 호출한다면 어떨까요? 아마도 writelines메서드를 호출 할까요? 그렇다면 예외가 있습니다.
miracle173 2014

5
실제 파일 이 필요한 경우에는 작동하지 않습니다 ( 예 : fileno().
Jonathon Reinhart

@JonathonReinhart이를 위해 요청에 따라 파일 설명자를 느리게 만들 수 있다고 가정합니다. os.open(os.devnull, os.O_RDWR)후속 호출에 대해 동일한 fd를 사용 하고 산출 할 수 있다고 가정합니다 fileno(어쨌든 모든 데이터가 삭제되기 때문에)
minmaxavg

당신도 필요합니다close()
shoosh

5
>>> import os
>>> os.devnull
'nul'

11
명확히하기 위해 Windows에서는 'nul'이 제공됩니다. Linux는 '/ dev / null'을 반환합니다.
Walter

5

아무것도하지 않는 파일 류 객체를 직접 만드시겠습니까?

class FakeSink(object):
    def write(self, *args):
        pass
    def writelines(self, *args):
        pass
    def close(self, *args):
        pass

1
관용적으로는 당신 말이 맞지만 'self'는 또 다른 매개 변수이며의 첫 번째 요소로 전달됩니다 args. 매개 변수를 사용하지 않기 때문에주의해야 할 유일한 이유는 미적입니다. 나는 ... 고칠거야
앤드류 Aylett에게

2
일부 작업은 'fileno'필요
조나단 하틀리을

2

저렴한 솔루션 경고!

class DevNull():
  def __init__(self, *args):
    self.closed = False
    self.mode = "w"
    self.name = "<null>"
    self.encoding = None
    self.errors = None
    self.newlines = None
    self.softspace = 0
  def close(self):
    self.closed == True
  @open_files_only
  def flush(self):
    pass
  @open_files_only
  def next(self):
    raise IOError("Invalid operation")
  @open_files_only
  def read(size = 0):
    raise IOError("Invalid operation")
  @open_files_only
  def readline(self):
    raise IOError("Invalid operation")
  @open_files_only
  def readlines(self):
    raise IOError("Invalid operation")
  @open_files_only
  def xreadlines(self):
    raise IOError("Invalid operation")
  @open_files_only
  def seek(self):
    raise IOError("Invalid operation")
  @open_files_only
  def tell(self):
    return 0
  @open_files_only
  def truncate(self):
    pass
  @open_files_only
  def write(self):
    pass
  @open_files_only
  def writelines(self):
    pass

def open_files_only(fun):
  def wrapper(self, *args):
    if self.closed:
      raise IOError("File is closed")
    else:
      fun(self, *args)
  return wrapper

난 그냥 재미를 위해 데코레이터를 던졌다 : D
badp

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