一. 背景
在Python中,文件對(duì)象sys.stdin、sys.stdout和sys.stderr分別對(duì)應(yīng)解釋器的標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)出錯(cuò)流。在程序啟動(dòng)時(shí),這些對(duì)象的初值由sys.__stdin__、sys.__stdout__和sys.__stderr__保存,以便用于收尾(finalization)時(shí)恢復(fù)標(biāo)準(zhǔn)流對(duì)象。
Windows系統(tǒng)中IDLE(Python GUI)由pythonw.exe,該GUI沒有控制臺(tái)。因此,IDLE將標(biāo)準(zhǔn)輸出句柄替換為特殊的PseudoOutputFile對(duì)象,以便腳本輸出重定向到IDLE終端窗口(Shell)。這可能導(dǎo)致一些奇怪的問題,例如:
Python 2.7.11 (v2.7.11:6d1b6a68f775, Dec 5 2015, 20:32:19) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import sys
>>> for fd in (sys.stdin, sys.stdout, sys.stderr): print fd
>>> for fd in (sys.__stdin__, sys.__stdout__, sys.__stderr__): print fd
', mode 'r' at 0x00FED020>
', mode 'w' at 0x00FED078>
', mode 'w' at 0x00FED0D0>
>>>
可以發(fā)現(xiàn),sys.__stdout__與sys.stdout取值并不相同。而在普通的Python解釋器下(如通過Windows控制臺(tái))運(yùn)行上述代碼時(shí),兩者取值相同。
print語句(statement)不以逗號(hào)結(jié)尾時(shí),會(huì)在輸出字符串尾部自動(dòng)附加一個(gè)換行符(linefeed);否則將一個(gè)空格代替附加的換行符。print語句默認(rèn)寫入標(biāo)準(zhǔn)輸出流,也可重定向至文件或其他可寫對(duì)象(所有提供write方法的對(duì)象)。這樣,就可以使用簡(jiǎn)潔的print語句代替笨拙的object.write('hello'+'\n')寫法。
由上可知,在Python中調(diào)用print obj打印對(duì)象時(shí),缺省情況下等效于調(diào)用sys.stdout.write(obj+'\n')
示例如下:
>>> import sys
>>> print 'Hello World'
Hello World
>>> sys.stdout.write('Hello World')
Hello World
二. 重定向方式
本節(jié)介紹常用的Python標(biāo)準(zhǔn)輸出重定向方式。這些方法各有優(yōu)劣之處,適用于不同的場(chǎng)景。
2.1 控制臺(tái)重定向
最簡(jiǎn)單常用的輸出重定向方式是利用控制臺(tái)命令。這種重定向由控制臺(tái)完成,而與Python本身無關(guān)。
Windows命令提示符(cmd.exe)和Linux Shell(bash等)均通過">"或">>"將輸出重定向。其中,">"表示覆蓋內(nèi)容,">>"表示追加內(nèi)容。類似地,"2>"可重定向標(biāo)準(zhǔn)錯(cuò)誤。重定向到"nul"(Windows)或"/dev/null"(Linux)會(huì)抑制輸出,既不屏顯也不存盤。
以Windows命令提示符為例,將Python腳本輸出重定向到文件(為縮短篇幅已刪除命令間空行):
E:\>echo print 'hello' > test.py
E:\>test.py > out.txt
E:\>type out.txt
hello
E:\>test.py >> out.txt
E:\>type out.txt
hello
hello
E:\>test.py > nul
注意,在Windows命令提示符中執(zhí)行Python腳本時(shí),命令行無需以"python"開頭,系統(tǒng)會(huì)根據(jù)腳本后綴自動(dòng)調(diào)用Python解釋器。此外,type命令可直接顯示文本文件的內(nèi)容,類似Linux系統(tǒng)的cat命令。
Linux Shell中執(zhí)行Python腳本時(shí),命令行應(yīng)以"python"開頭。除">"或">>"重定向外,還可使用tee命令。該命令可將內(nèi)容同時(shí)輸出到終端屏幕和(多個(gè))文件中,"-a"選項(xiàng)表示追加寫入,否則覆蓋寫入。示例如下(echo $SHELL或echo $0顯示當(dāng)前所使用的Shell):
[wangxiaoyuan_@localhost ~]$ echo $SHELL
/bin/bash
[wangxiaoyuan_@localhost ~]$ python -c "print 'hello'"
hello
[wangxiaoyuan_@localhost ~]$ python -c "print 'hello'" > out.txt
[wangxiaoyuan_@localhost ~]$ cat out.txt
hello
[wangxiaoyuan_@localhost ~]$ python -c "print 'world'" >> out.txt
[wangxiaoyuan_@localhost ~]$ cat out.txt
hello
world
[wangxiaoyuan_@localhost ~]$ python -c "print 'I am'" | tee out.txt
I am
[wangxiaoyuan_@localhost ~]$ python -c "print 'xywang'" | tee -a out.txt
xywang
[wangxiaoyuan_@localhost ~]$ cat out.txt
I am
xywang
[wangxiaoyuan_@localhost ~]$ python -c "print 'hello'" > /dev/null
[wangxiaoyuan_@localhost ~]$
若僅僅想要將腳本輸出保存到文件中,也可直接借助會(huì)話窗口的日志抓取功能。
注意,控制臺(tái)重定向的影響是全局性的,僅適用于比較簡(jiǎn)單的輸出任務(wù)。
2.2 print >>重定向
這種方式基于print語句的擴(kuò)展形式,即"print obj >> expr"。其中,obj為一個(gè)file-like(尤其是提供write方法的)對(duì)象,為None時(shí)對(duì)應(yīng)標(biāo)準(zhǔn)輸出(sys.stdout)。expr將被輸出到該文件對(duì)象中。
示例如下:
memo = cStringIO.StringIO(); serr = sys.stderr; file = open('out.txt', 'w+')
print >>memo, 'StringIO'; print >>serr, 'stderr'; print >>file, 'file'
print >>None, memo.getvalue()
上述代碼執(zhí)行后,屏顯為"serr"和"StringIO"(兩行,注意順序),out.txt文件內(nèi)寫入"file"。
可見,這種方式非常靈活和方便。缺點(diǎn)是不適用于輸出語句較多的場(chǎng)景。
評(píng)論
查看更多