<pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

                    10.2. 標準輸入、輸出和錯誤

                    UNIX 用戶已經對標準輸入、標準輸出和標準錯誤的概念非常熟悉了。這一節是為其他不熟悉的人準備的。

                    標準輸入和標準錯誤 (通常縮寫為 stdoutstderr) 是內建在每一個 UNIX 系統中的管道。當你 print 某些東西時,結果前往 stdout 管道;當你的程序崩潰并打印出調試信息 (例如 Python 中的 traceback (錯誤跟蹤)) 的時候,信息前往 stderr 管道。通常這兩個管道只與你正在工作的終端窗口相聯,所以當一個程序打印時,你可以看到輸出,而當一個程序崩潰時,你可以看到調試信息。(如果你正在一個基于窗口的 Python IDE 上工作,stdoutstderr 缺省為你的“交互窗口”。)

                    例 10.8. stdoutstderr 介紹

                    >>> for i in range(3):
                    ...     print 'Dive in'             1
                    Dive in
                    Dive in
                    Dive in
                    >>> import sys
                    >>> for i in range(3):
                    ...     sys.stdout.write('Dive in') 2
                    Dive inDive inDive in
                    >>> for i in range(3):
                    ...     sys.stderr.write('Dive in') 3
                    Dive inDive inDive in
                    1 正如在例 6.9 “簡單計數”中看到的,你可以使用 Python 內置的 range 函數來構造簡單的計數循環,即重復某物一定的次數。
                    2 stdout 是一個類文件對象;調用它的 write 函數可以打印出你給定的任何字符串。實際上,這就是 print 函數真正做的事情;它在你打印的字符串后面加上一個硬回車,然后調用 sys.stdout.write 函數。
                    3 在最簡單的例子中,stdoutstderr 把它們的輸出發送到相同的地方:Python IDE (如果你在一個 IDE 中的話),或者終端 (如果你從命令行運行 Python 的話)。和 stdout 一樣,stderr 并不為你添加硬回車;如果需要,要自己加上。

                    stdoutstderr 都是類文件對象,就像在第 10.1 節 “抽象輸入源”中討論的一樣,但是它們都是只寫的。它們都沒有 read 方法,只有 write 方法。然而,它們仍然是類文件對象,因此你可以將其它任何 (類) 文件對象賦值給它們來重定向其輸出。

                    例 10.9. 重定向輸出

                    [you@localhost kgp]$ python stdout.py
                    Dive in
                    [you@localhost kgp]$ cat out.log
                    This message will be logged instead of displayed

                    (在 Windows 上,你要使用 type 來代替 cat 顯示文件的內容。)

                    如果您還沒有下載本書附帶的樣例程序, 可以 下載本程序和其他樣例程序

                    #stdout.py
                    import sys
                    
                    print 'Dive in'                                          1
                    saveout = sys.stdout                                     2
                    fsock = open('out.log', 'w')                             3
                    sys.stdout = fsock                                       4
                    print 'This message will be logged instead of displayed' 5
                    sys.stdout = saveout                                     6
                    fsock.close()                                            7
                    
                    1 打印輸出到 IDE交互窗口” (或終端,如果從命令行運行腳本的話)。
                    2 始終在重定向前保存 stdout,這樣的話之后你還可以將其設回正常。
                    3 打開一個新文件用于寫入。如果文件不存在,將會被創建。如果文件存在,將被覆蓋。
                    4 所有后續的輸出都會被重定向到剛才打開的新文件上。
                    5 這樣只會將輸出結果“打印”到日志文件中;在 IDE 窗口中或在屏幕上不會看到輸出結果。
                    6 在我們將 stdout 搞亂之前,讓我們把它設回原來的方式。
                    7 關閉日志文件。

                    重定向 stderr 以完全相同的方式進行,只要把 sys.stdout 改為 sys.stderr

                    例 10.10. 重定向錯誤信息

                    [you@localhost kgp]$ python stderr.py
                    [you@localhost kgp]$ cat error.log
                    Traceback (most recent line last):
                      File "stderr.py", line 5, in ?
                        raise Exception, 'this error will be logged'
                    Exception: this error will be logged

                    如果您還沒有下載本書附帶的樣例程序, 可以 下載本程序和其他樣例程序

                    #stderr.py
                    import sys
                    
                    fsock = open('error.log', 'w')               1
                    sys.stderr = fsock                           2
                    raise Exception, 'this error will be logged' 3 4
                    
                    1 打開你要存儲調試信息的日志文件。
                    2 將新打開的日志文件的文件對象賦值給 stderr 以重定向標準錯誤。
                    3 引發一個異常。從屏幕輸出上可以注意到這個行為沒有 在屏幕上打印出任何東西。所有正常的跟蹤信息已經寫進 error.log
                    4 還要注意你既沒有顯式關閉日志文件,也沒有將 stderr 設回最初的值。這樣挺好,因為一旦程序崩潰 (由于引發的異常),Python 將替我們清理并關閉文件,因此永遠不恢復 stderr 不會造成什么影響。然而對于 stdout,恢復初始值相對更為重要――你可能會在后面再次操作標準輸出。

                    向標準錯誤寫入錯誤信息是很常見的,所以有一種較快的語法可以立刻導出信息。

                    例 10.11. 打印到 stderr

                    >>> print 'entering function'
                    entering function
                    >>> import sys
                    >>> print >> sys.stderr, 'entering function' 1
                    entering function
                    
                    1 print 語句的快捷語法可以用于寫入任何打開的文件 (或者是類文件對象)。在這里,你可以將單個 print 語句重定向到 stderr 而且不用影響后面的 print 語句。

                    另一方面,標準輸入是一個只讀文件對象,它表示從前一個程序到這個程序的數據流。這個對于老的 Mac OS 用戶和 Windows 用戶可能不太容易理解,除非你受到過 MS-DOS 命令行的影響。在 MS-DOS 命令行中,你可以使用一行指令構造一個命令的鏈,使得一個程序的輸出就可以成為下一個程序的輸入。第一個程序只是簡單地輸出到標準輸出上 (程序本身沒有做任何特別的重定向,只是執行了普通的 print 語句等),然后,下一個程序從標準輸入中讀取,操作系統就把一個程序的輸出連接到一個程序的輸入。

                    例 10.12. 鏈接命令

                    [you@localhost kgp]$ python kgp.py -g binary.xml         1
                    01100111
                    [you@localhost kgp]$ cat binary.xml                      2
                    <?xml version="1.0"?>
                    <!DOCTYPE grammar PUBLIC "-//diveintopython.org//DTD Kant Generator Pro v1.0//EN" "kgp.dtd">
                    <grammar>
                    <ref id="bit">
                      <p>0</p>
                      <p>1</p>
                    </ref>
                    <ref id="byte">
                      <p><xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/>\
                    <xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/></p>
                    </ref>
                    </grammar>
                    [you@localhost kgp]$ cat binary.xml | python kgp.py -g - 3 4
                    10110001
                    1 正如你在第 9.1 節 “概覽”中看到的,該命令將只打印一個隨機的八位字符串,其中只有 0 或者 1
                    2 該處只是簡單地打印出整個 binary.xml 文檔的內容。(Windows 用戶應該用 type 代替 cat。)
                    3 該處打印 binary.xml 的內容,但是“|”字符,稱為“管道”符,說明內容不會打印到屏幕上;它們會成為下一個命令的標準輸入,在這個例子中是你調用的 Python 腳本。
                    4 為了不用指定一個文件 (例如 binary.xml),你需要指定“-”,它會使得你的腳本從標準輸入載入腳本,而不是從磁盤上的特定文件。 (下一個例子更多地說明了這是如何實現的)。所以效果和第一種語法是一樣的,在那里你要直接指定語法文件,但是想想這里的擴展性。讓我們把 cat binary.xml 換成別的什么東西――例如運行一個腳本動態生成語法――然后通過管道將它導入你的腳本。它可以來源于任何地方:數據庫,或者是生成語法的元腳本,或者其他。你根本不需要修改你的 kgp.py 腳本就可以并入這個功能。你要做的僅僅是從標準輸入取得一個語法文件,然后你就可以將其他的邏輯分離出來,放到另一程序中去了。

                    那么腳本是如何“知道”在語法文件是“-”時從標準輸入讀取? 其實不神奇;它只是代碼。

                    例 10.13. 在 kgp.py 中從標準輸入讀取

                    
                    def openAnything(source):
                        if source == "-":    1
                            import sys
                            return sys.stdin
                    
                        # try to open with urllib (if source is http, ftp, or file URL)
                        import urllib
                        try:
                    
                    [... snip ...]
                    1 這是 toolbox.py 中的 openAnything 函數,以前在第 10.1 節 “抽象輸入源”中你已經檢視過了。所有你要做的就是在函數的開始加入 3 行代碼來檢測源是否是“-”;如果是,返回 sys.stdin。就這么簡單!記住,stdin 是一個擁有 read 方法的類文件對象,所以其它的代碼 (在 kgp.py 中,在那里你調用了 openAnything) 一點都不需要改動。

                      <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
                      <pre id="vvttv"></pre>

                        <p id="vvttv"></p>

                            <p id="vvttv"></p>

                                  <p id="vvttv"></p>

                                  <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                                    <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                                      <p id="vvttv"></p>

                                      这里只有精品视频