2013-07-19 77 views
2

在交互式控制檯:如何恢復sys.stdout.close()?

>>> import sys 
>>> sys.stdout 
<open file '<stdout>', mode 'w' at 0xb7810078> 
>>> sys.stdout.close() 
>>> sys.stdout # confirming that it's closed 
(...) ValueError: I/O operation on closed file 

試圖還原:

>>> sys.stdout.open() 
(...) AttributeError: 'file' object has no attribute 'open' 
>>> sys.stdout.write('foo') 
(...) ValueError: I/O operation on closed file 

我同意這是一個無聊的問題,但我很好奇怎麼sys.stdout.close()可以被還原Python(當然,無需重新啓動交互式控制檯)以及爲什麼sys.stdout.open()沒有意義。

回答

0

sys.stdout.open()沒有任何意義,因爲open將文件名和模式作爲參數,而封閉流對象沒有打開的方法。

主要答案是不要在第一時間關閉它!

7

好了,所以我希望你是在UNIX系統上...

基本上sys.stdout來只是包含任何可寫對象的變量。

因此,我們可以做到像魔

sys.stdout = open("file", "w") 

現在我們可以寫入該文件,如果它是標準輸出。

瞭解unix只是一大盒文件。 Unix的是一種足以給我們/dev/stdout

所以要重新打開標準輸出其簡單

sys.stdout = open("/dev/stdout", "w") 

工作完成後,你現在有一個新的標準輸出打開。

編輯

>>> os.fstat(1) 
posix.stat_result(st_mode=8592, st_ino=7, st_dev=11L, st_nlink=1, st_uid=1000, st_gid=5, st_size=0, st_atime=1374230552, st_mtime=1374230552, st_ctime=1374230434) 
>>> sys.stdout.close() 
>>> sys.stdout = open("/dev/stdout", "w") 
>>> sys.stdout.fileno() 
3 
>>> os.fstat(3) 
posix.stat_result(st_mode=8592, st_ino=7, st_dev=11L, st_nlink=1, st_uid=1000, st_gid=5, st_size=0, st_atime=1374230576, st_mtime=1374230576, st_ctime=1374230434) 
>>> os.fstat(1) 
posix.stat_result(st_mode=8592, st_ino=7, st_dev=11L, st_nlink=1, st_uid=1000, st_gid=5, st_size=0, st_atime=1374230576, st_mtime=1374230576, st_ctime=1374230434) 
>>> 
+0

不錯的提示,我應該想到它。謝謝。 – ammt

5

在你的情況,你可以通過sys.stdout = os.fdopen(1, 'w', 0)得到sys.stdout回來。

但是,事實上,你真的不關閉sys.stdout。如果你想完全關閉它,你必須使用os.close(sys.stdout.fileno())。你可以閱讀Why doesn’t closing sys.stdout (stdin, stderr) really close it?爲什麼。在這種情況下,我不知道如何重新打開它。上述方法甚至open('/dev/stdout', 'w')在我的Linux上都失敗了。

+0

感謝您的額外信息。 – ammt

+0

最棒的是你的解決方案不是Unix特有的。 – ammt

0

爲什麼sys.stdout.open()沒有意義,而sys.stdout.close()(儘管有明顯的對稱性)的原因是.open()和.close()適用於流/文件,sys.stdout只是一個指針(sys.stdout在後者關閉後不會指向任何流/文件)。