Nền tảng chéo / dev / null bằng Python


83

Tôi đang sử dụng mã sau để ẩn stderr trên Linux / OSX cho thư viện Python mà tôi không kiểm soát việc ghi vào stderr theo mặc định:

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

Có một nền tảng chéo dễ dàng thay thế cho / dev / null không? Lý tưởng nhất là nó sẽ không tiêu tốn bộ nhớ vì đây là một quá trình chạy lâu dài.


1
có thể trùng lặp của / dev / null trong Windows?
msw

8
@msw: Tôi không nghĩ vậy, Python có nhiều cách hơn để bạn có thể giải quyết vấn đề này.
Andrew Aylett

Câu trả lời:



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

zookeeper.set_log_stream(Devnull())

os.devnullTất nhiên, việc mở cũng tốt, nhưng theo cách này, mọi hoạt động đầu ra xảy ra (dưới dạng noop) "trong quá trình" - không có chuyển đổi ngữ cảnh sang HĐH và quay lại, và cũng không có bộ đệm (trong khi một số bộ đệm thường được sử dụng bởi một open) và do đó thậm chí ít tiêu thụ bộ nhớ hơn.


6
Tôi hiểu rằng việc sử dụng os.devnull có thể tạo ra một số chi phí. Nhưng nếu một người sử dụng đối tượng của bạn, điều gì sẽ xảy ra nếu đối tượng writeZookeeper gọi các phương thức khác sau đó đối tượng tệp log_stream của nó? Có lẽ nó gọi writelinesphương thức? Sau đó, có một ngoại lệ.
Phép màu173,

5
Điều này không hoạt động khi bạn cần một tệp thực , chẳng hạn như tệp có fileno().
Jonathon Reinhart

@JonathonReinhart Đối với điều đó, tôi cho rằng bạn có thể tạo trình mô tả tệp một cách lười biếng theo yêu cầu, bằng cách sử dụng os.open(os.devnull, os.O_RDWR) và năng suất các fd tương tự cho cuộc gọi tiếp theo để fileno(vì tất cả dữ liệu sẽ bị loại bỏ anyway)
minmaxavg

Bạn cũng sẽ cầnclose()
shoosh

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

11
Chỉ cần làm rõ: 'nul' được cung cấp trên Windows. Linux sẽ trả về '/ dev / null'.
Walter

5

Tạo đối tượng giống tệp của riêng bạn mà không làm gì cả?

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

1
Nói một cách thành ngữ, bạn đúng, nhưng 'self' chỉ là một tham số khác và sẽ được chuyển vào dưới dạng phần tử đầu tiên của args. Vì chúng tôi không sử dụng bất kỳ thông số nào, lý do duy nhất để quan tâm là thẩm mỹ. Tôi sẽ sửa chữa nó ...
Andrew Aylett

2
Một số hoạt động cũng cần 'fileno'
Jonathan Hartley

2

Cảnh báo giải pháp giá rẻ!

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

Tôi ném vào một bộ trang trí chỉ để giải trí: D
badp

Cũng cần nhậpxuất cảnh ?
user48956 11/02/16
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.