UNIX用户已经对标准输入、标准输出和标准错误的概念熟悉了。这一节是为其它不熟悉的人准备的。
标准输出和标准错误(通常缩写为 stdout 和 stderr)是建立在每个UNIX系统内的管道(pipe)。当你 print 某东西时,结果输出到 stdout 管道中;当你的程序崩溃并打印出调试信息时(象Python中的错误跟踪),结果输出到 stderr 管道中。通常这两个管道只与你正在工作的终端窗口相联,所以当一个程序打印输出时,你可以看到输出,并且当一个程序崩溃时,你可以看到调试信息。(如果你在一个基于窗口的Python IDE系统上工作,stdout 和 stderr 缺省为“交互窗口”。)
<tt>>>> </tt><span class="userinput"><span class="pykeyword" style="font-weight: bold; color: navy; background-color: white;">for</span> i <span class="pykeyword" style="font-weight: bold; color: navy; background-color: white;">in</span> range(3):</span> <tt>... </tt><span class="userinput"><span class="pykeyword" style="font-weight: bold; color: navy; background-color: white;">print</span> <span class="pystring" style="color: olive; background-color: white;">'Dive in'</span></span> <a target=_blank target="_blank" name="kgp.stdio.1.1" style="color: rgb(202, 0, 0);"></a><img src="https://i-blog.csdnimg.cn/blog_migrate/94f2f802927bdd6e1d78f98034bd14ae.png" alt="1" border="0" width="12" height="12" style="border: none; max-width: 100%;" /> <span class="computeroutput" style="color: teal; background-color: white;">Dive in Dive in Dive in</span> <tt>>>> </tt><span class="userinput"><span class="pykeyword" style="font-weight: bold; color: navy; background-color: white;">import</span> sys</span> <tt>>>> </tt><span class="userinput"><span class="pykeyword" style="font-weight: bold; color: navy; background-color: white;">for</span> i <span class="pykeyword" style="font-weight: bold; color: navy; background-color: white;">in</span> range(3):</span> <tt>... </tt><span class="userinput">sys.stdout.write(<span class="pystring" style="color: olive; background-color: white;">'Dive in'</span>)</span> <a target=_blank target="_blank" name="kgp.stdio.1.2" style="color: rgb(202, 0, 0);"></a><img src="https://i-blog.csdnimg.cn/blog_migrate/b521675a112d782b4af4bffabf657a91.png" alt="2" border="0" width="12" height="12" style="border: none; max-width: 100%;" /> <span class="computeroutput" style="color: teal; background-color: white;">Dive inDive inDive in</span> <tt>>>> </tt><span class="userinput"><span class="pykeyword" style="font-weight: bold; color: navy; background-color: white;">for</span> i <span class="pykeyword" style="font-weight: bold; color: navy; background-color: white;">in</span> range(3):</span> <tt>... </tt><span class="userinput">sys.stderr.write(<span class="pystring" style="color: olive; background-color: white;">'Dive in'</span>)</span> <a target=_blank target="_blank" name="kgp.stdio.1.3" style="color: rgb(202, 0, 0);"></a><img src="https://i-blog.csdnimg.cn/blog_migrate/ec7677572d2e5f818584b93441107410.png" alt="3" border="0" width="12" height="12" style="border: none; max-width: 100%;" /> <span class="computeroutput" style="color: teal; background-color: white;">Dive inDive inDive in</span>
![]() | 正如我们在例 3.28中看到的,我们可以使用Python内置的 range 函数来创建简单的计数循环,即重复某物一定的次数。 |
![]() | stdout 是一个类文件对象;调用它的 write 函数会打印出任何给出的字符串。事实上,这就是 print 函数真正所做的;它会在正打印的字符串后面加上回车换行符,并调用sys.stdout.write。 |
![]() | 在最简单的例子中,stdout 和 stderr 将它们的输出发送到同一个地方:Python IDE,或终端(如果你正从命令行运行Python)。象 stdout,stderr 并不为你增加回车换行符;如果需要,要自已加上。 |
stdout 和 stderr 都是类文件对象,就象我们在提取输入源中所讨论的一样,但它们都是只写的。它们没有 read 方法,只有 write。然而,它们的确是类文件对象,并且你可以将任意文件对象或类文件对象赋给它们来重定向输出。
<tt>[f8dy@oliver kgp]$ </tt><span class="userinput">python2 stdout.py</span> <span class="computeroutput" style="color: teal; background-color: white;">Dive in</span> <tt>[f8dy@oliver kgp]$ </tt><span class="userinput">cat out.log</span> <span class="computeroutput" style="color: teal; background-color: white;">This message will be logged instead of displayed</span>
如果你还没有这样做,你可以下载本书中用到的本例和其它例子。
<span class="pycomment" style="color: green; font-style: italic; background-color: white;">#stdout.py</span> <span class="pykeyword" style="font-weight: bold; color: navy; background-color: white;">import</span> sys <span class="pykeyword" style="font-weight: bold; color: navy; background-color: white;">print</span> <span class="pystring" style="color: olive; background-color: white;">'Dive in'</span> <a target=_blank target="_blank" name="kgp.stdio.2.1" style="color: rgb(202, 0, 0);"></a><img src="https://i-blog.csdnimg.cn/blog_migrate/94f2f802927bdd6e1d78f98034bd14ae.png" alt="1" border="0" width="12" height="12" style="border: none; max-width: 100%;" /> saveout = sys.stdout <a target=_blank target="_blank" name="kgp.stdio.2.2" style="color: rgb(202, 0, 0);"></a><img src="https://i-blog.csdnimg.cn/blog_migrate/b521675a112d782b4af4bffabf657a91.png" alt="2" border="0" width="12" height="12" style="border: none; max-width: 100%;" /> fsock = open(<span class="pystring" style="color: olive; background-color: white;">'out.log'</span>, <span class="pystring" style="color: olive; background-color: white;">'w'</span>) <a target=_blank target="_blank" name="kgp.stdio.2.3" style="color: rgb(202, 0, 0);"></a><img src="https://i-blog.csdnimg.cn/blog_migrate/ec7677572d2e5f818584b93441107410.png" alt="3" border="0" width="12" height="12" style="border: none; max-width: 100%;" /> sys.stdout = fsock <a target=_blank target="_blank" name="kgp.stdio.2.4" style="color: rgb(202, 0, 0);"></a><img src="https://i-blog.csdnimg.cn/blog_migrate/612c9a565086cec253efa867939d595b.png" alt="4" border="0" width="12" height="12" style="border: none; max-width: 100%;" /><span class="pykeyword" style="font-weight: bold; color: navy; background-color: white;"> print</span> <span class="pystring" style="color: olive; background-color: white;">'This message will be logged instead of displayed'</span> <a target=_blank target="_blank" name="kgp.stdio.2.5" style="color: rgb(202, 0, 0);"></a><img src="https://i-blog.csdnimg.cn/blog_migrate/ef494d9cd81d858ff5770e066a8d9e34.png" alt="5" border="0" width="12" height="12" style="border: none; max-width: 100%;" /> sys.stdout = saveout <a target=_blank target="_blank" name="kgp.stdio.2.6" style="color: rgb(202, 0, 0);"></a><img src="https://i-blog.csdnimg.cn/blog_migrate/6cbe398126f16a73462868d589ab721e.png" alt="6" border="0" width="12" height="12" style="border: none; max-width: 100%;" /> fsock.close() <a target=_blank target="_blank" name="kgp.stdio.2.7" style="color: rgb(202, 0, 0);"></a><img src="https://i-blog.csdnimg.cn/blog_migrate/23b6869f4862967756e6c880cf79e738.png" alt="7" border="0" width="12" height="12" style="border: none; max-width: 100%;" />
重定向 stderr 完全以相同的方式进行,用 sys.stderr 代替 sys.stdout。
<tt>[f8dy@oliver kgp]$ </tt><span class="userinput">python2 stderr.py</span> <tt>[f8dy@oliver kgp]$ </tt><span class="userinput">cat error.log</span> <span class="computeroutput" style="color: teal; background-color: white;">Traceback (most recent line last): File "stderr.py", line 5, in ? raise Exception, 'this error will be logged' Exception: this error will be logged</span>
如果你还没有这样做,你可以下载本书中用到的本例和其它例子。
<span class="pycomment" style="color: green; font-style: italic; background-color: white;">#stderr.py</span> <span class="pykeyword" style="font-weight: bold; color: navy; background-color: white;">import</span> sys fsock = open(<span class="pystring" style="color: olive; background-color: white;">'error.log'</span>, <span class="pystring" style="color: olive; background-color: white;">'w'</span>) <a target=_blank target="_blank" name="kgp.stdio.3.1" style="color: rgb(202, 0, 0);"></a><img src="https://i-blog.csdnimg.cn/blog_migrate/94f2f802927bdd6e1d78f98034bd14ae.png" alt="1" border="0" width="12" height="12" style="border: none; max-width: 100%;" /> sys.stderr = fsock <a target=_blank target="_blank" name="kgp.stdio.3.2" style="color: rgb(202, 0, 0);"></a><img src="https://i-blog.csdnimg.cn/blog_migrate/b521675a112d782b4af4bffabf657a91.png" alt="2" border="0" width="12" height="12" style="border: none; max-width: 100%;" /><span class="pykeyword" style="font-weight: bold; color: navy; background-color: white;"> raise</span> Exception, <span class="pystring" style="color: olive; background-color: white;">'this error will be logged'</span> <a target=_blank target="_blank" name="kgp.stdio.3.3" style="color: rgb(202, 0, 0);"></a><img src="https://i-blog.csdnimg.cn/blog_migrate/ec7677572d2e5f818584b93441107410.png" alt="3" border="0" width="12" height="12" style="border: none; max-width: 100%;" /> <a target=_blank target="_blank" name="kgp.stdio.3.4" style="color: rgb(202, 0, 0);"></a><img src="https://i-blog.csdnimg.cn/blog_migrate/612c9a565086cec253efa867939d595b.png" alt="4" border="0" width="12" height="12" style="border: none; max-width: 100%;" />
另一方面,标准输入是只读文件对象,同时它表示从前面某个程序的数据流入这个程序。这一点可能对典型的Mac OS用户可能没什么意义,或者甚至是对Windows用户也是如此,除非你更习惯在MS-DOS命令行下工作。它的工作方式是:你可以在单个文件中构造一个命令行的链,这样一个程序的输出成为链中下一个程序的输入。第一个程序简单地输出到标准输出(本身不需要任何特别的重定义,只是执行正常的 print 什么的),同时下个程序从标准输入读入,操作系统会小心地将一个程序的输出连接到下一个程序的输入。