2015-06-21 14 views
0

有一個名爲redirect的函數,它將文件source上的操作臨時重定向到文件targetsys .__ stdout__正常工作,但sys.stdout不正確

def redirect(source, target): 
    source.flush() 
    fd = source.fileno() 
    with os.fdopen(os.dup(fd), source.mode) as source2: 
     os.dup2(target.fileno(), fd) 
     try: 
      yield 
     finally: 
      source.flush() 
      os.dup2(source2.fileno(), fd) 

它正在從相同的模塊稱爲

with tempfile.TemporaryFile() as tmp: 
     with redirect(sys.stdout, tmp), nogil: 

在編譯時,它用來產生一個AttributeError

AttributeError: StringIO instance has no attribute 'fileno' 

在線路fd = source.fileno()

但是當我將sys.stdout替換爲sys.__stdout__時,沒有這樣的錯誤,測試成功通過。

現在我真的很困惑,爲什麼__stdout__工作,但不是stdout

+0

您是從IDLE環境還是從其他IDE運行程序?我想如果你從系統命令行運行你的程序,你會得到一個真實的'sys.stdout'文件。 –

+0

我從終端運行nosetests –

+3

啊,是的,鼻子測試的實現可能用'StringIO'對象替換'sys.stdout',以便它可以輕鬆捕獲輸出。這聽起來像鼻子測試不符合你試圖在它下面運行的功能。 –

回答

0

正如格雷格在評論中提到的,那是行不通的。我通常做的是暫時改變我的標準輸出。

@contextmanager 
def replace_stdout(replacement): 
    _stdout = sys.stdout 
    sys.stdout = replacement 
    try: 
     yield 
    finally: 
     sys.stdout = _stdout 

並使用與上下文管理器:

with tempfile.TemporaryFile() as tmp: 
    with replace_stdout(sys.stdout, tmp): 

此慣例並不關心最初的標準輸出是否具有FD與否。