在Python中跨平台/ dev / null


83

我正在使用以下代码在Linux / OSX上为Python库隐藏stderr,但我不控制默认情况下写入stderr的Python库:

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

是否有一个简单的跨平台替代/ dev / null?理想情况下,它不会消耗内存,因为这是一个长期运行的过程。



8
@msw:我不这么认为,Python有更多方法可以解决此问题。
安德鲁·艾丽特

Answers:



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

zookeeper.set_log_stream(Devnull())

os.devnull当然,打开也可以,但是这样,每个输出操作都会“进行中”(作为noop)发生-没有上下文切换到操作系统,也没有缓冲(虽然缓冲通常由来使用open),因此甚至更少的内存消耗。


6
我了解使用os.devnull可能会产生一些开销。但是,如果使用您的对象,而zookeeper对象又调用write其log_stream文件对象的其他方法,该怎么办?也许它调用了writelines方法?然后有一个例外。
miracle173'4

5
当您需要一个真实文件(例如,带有的文件)时,此功能将无效fileno()
乔纳森·莱因哈特

@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”。
沃尔特

5

创建自己的不执行任何操作的类似文件的对象?

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

1
习惯上来说,您是对的,但是'self'只是另一个参数,将作为的第一个元素传入args。由于我们不使用任何参数,因此关心的唯一原因是美观。我会解决的…
安德鲁·艾丽特

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 2010年

还需要进入退出吗?
user48956 '02
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.