Python中的標准輸入,輸出與錯誤


標准輸出和標准錯誤(通常縮寫為stdoutstderr )是內置在所有類unix系統中的管道,包括Mac OS X和Linux。當你調用print()函數時,你要打印的東西被發送到stdout 管道。當你的程序崩潰並打印出一個回溯信息時,它會轉到stderr管道。默認情況下,這兩個管道都只是連接到工作的終端窗口;當你的程序打印一些東西時,你會在你的終端窗口中看到輸出,當一個程序崩潰時,你也會在你的終端窗口中看到回溯。在圖形Python Shell中,stdout stderr管道默認為你的交互式窗口

for i in range(3):
...  print('PapayaWhip') ①
PapayaWhip # 有換行
PapayaWhip
PapayaWhip
>>> import sys
>>> for i in range(3):
...  l = sys.stdout.write('is the') ②
is theis theis the # 沒有換行
>>> for i in range(3):
...  l = sys.stderr.write('new black') ③
new blacknew blacknew black
print() 函數
stdout定義在sys模塊中,它是一個stream對象。調用它的write() 函數將打印出你給它的任何字符串,然后返回輸出的長度。事實上,這就是print 函數真正做的事情;它在打印的字符串末尾添加一個回車,並調用sys.stdout.write
在最簡單的情況下,sys.stdoutsys.stderr將它們的輸出發送到相同的地方:Python ide,或者終端(如果是從命令行運行Python)。和標准輸出一樣,標准錯誤不會為您添加回車。如果你想要回車,你需要添加回車符。

sys.stdoutsys.stderr是流對象,但它們是只寫的,嘗試調用它們的read()方法將觸發IOError

>>> import sys
>>> sys.stdout.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: not readable

重定向標准輸出

sys.stdoutsys.stderr 都是流對象,盡管它們只支持寫入。但它們不是常數,而是變量。這意味着我們可以為它們分配一個新值——任何其他流對象——來重定向它們的輸出。

#stdout.py
import sys

class RedirectStdoutTo:
    def __init__(self, out_new):
        self.out_new = out_new

    def __enter__(self):  # 進入上下文管理器執行
        self.out_old = sys.stdout # backup sys.stdout
        sys.stdout = self.out_new  # 重定向

    def __exit__(self, *args):  # 退出上下文管理器執行
        sys.stdout = self.out_old

print('A')
with open('out.log', mode='w', encoding='utf-8') as a_file, RedirectStdoutTo(a_file):  # with, 此處接了兩個上下文管理器
    print('B')
print('C')

# 標准輸出重定向到一個文件中去

Check this out:

you@localhost:~/diveintopython3/examples$ python3 stdout.py
A
C
you@localhost:~/diveintopython3/examples$ cat out.log
B

注意:Python 3.1之后單個with語句才支持多上下文管理器。

先瞅瞅最后一部分。

print('A')
with open('out.log', mode='w', encoding='utf-8') as a_file, RedirectStdoutTo(a_file):
    print('B')
print('C')

這是一個復雜的with語句,可以改寫成更易讀些:

with open('out.log', mode='w', encoding='utf-8') as a_file:
    with RedirectStdoutTo(a_file):
        print('B')

正如重寫所示,實際上有兩個 with 語句,其中一個嵌套在另一個的作用域中。外層的 with語句現在應該很熟悉了:它會打開一個名為out.log utf-8編碼的文本文件,將流對象賦給一個名為a_file的變量。但奇怪的地方在於:

with RedirectStdoutTo(a_file):

as語句去哪了?with語句實際上並不一定需要這個。就像你可以調用一個函數並忽略它的返回值一樣,你可以有一個with語句,並不把with上下文賦值給一個變量。

看一下RedirectStdoutTo類的內部。這個類是一個自定義上下文管理器。任何類都可以通過定義兩個特殊方法: __enter__()__exit__())成為上下文管理器。

重定向標准錯誤方法是一樣的了, sys.stderr代替 sys.stdout即可.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM