2010-05-28 81 views
66

我使用下面的代碼隱藏一個Python庫我不控制在Linux/OSX標準錯誤默認情況下,寫至標準錯誤:跨平臺的/ dev/Python中的空

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

是否有輕鬆跨平臺替代/ dev/null?理想情況下,它不會消耗內存,因爲這是一個漫長的過程。

+1

的可能重複(http://stackoverflow.com/questions/313111/dev-null-in-windows) – msw 2010-05-28 14:39:18

+8

@msw [的/ dev/null的在Windows?]:我不這麼認爲, Python有更多方法可以處理這個問題。 – 2010-05-28 14:45:15

回答

110

os.devnull怎麼樣?

import os 
f = open(os.devnull,"w") 
zookeeper.set_log_stream(f) 
4
>>> import os 
>>> os.devnull 
'nul' 
+9

只是爲了澄清:'nul'是在Windows上給出的。 Linux將返回'/ dev/null'。 – Walter 2010-05-28 14:42:50

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

zookeeper.set_log_stream(Devnull()) 

開放os.devnull是太細當然,但是這種方式產生的每個輸出操作(作爲一個空操作)「處理中」 - 沒有上下文切換到OS和背面,並且還沒有緩衝(而一些緩衝通常由open使用),因此更少的內存消耗。

+6

我知道使用os.devnull可能會產生一些開銷。但是如果有人使用你的對象,如果zookeeper對象調用其他方法,那麼'寫入'它的log_stream文件對象怎麼辦?也許它會調用'writelines'方法?然後有一個例外。 – miracle173 2014-04-05 09:50:40

+2

當您需要*真實*文件時,這不起作用,例如一個用'fileno()'。 – 2015-04-07 22:48:24

+0

@JonathonReinhart爲此,我想你可以根據請求使用'os.open(os.devnull,os.O_RDWR)'來創建文件描述符,並且隨後調用'fileno'時產生相同的fd(因爲所有的數據都是拋棄) – minmaxavg 2017-08-29 10:08:07

5

創建你自己的文件類對象,它什麼都不做?

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

在習慣上,你是對的,但'自己'只是另一個參數,將作爲'args'的第一個元素傳入。由於我們不使用任何參數,因此唯一的理由就是審美。我會修復它... – 2010-05-29 09:41:41

+1

一些操作也需要'fileno' – 2015-05-27 09:17:06

1

便宜的解決方案警告!

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 
+0

我扔了一個裝飾器只是爲了好玩:D – badp 2010-05-28 14:52:17

+0

還需要__enter__和__exit__? – user48956 2016-02-11 18:28:16

+0

@ user48956可能;這個答案已經快六歲了... – badp 2016-02-11 20:17:10