万代hg00量子:Python 中的输入,输出重定向

来源:百度文库 编辑:偶看新闻 时间:2024/05/05 15:01:52

我们知道通常情况下,shell环境中的标准输入(STDIN)流,标准输出(STDOUT)流,标准出错(STDERR)流分别指向键盘,屏幕,屏幕。
也就是说当我们在shell中执行一个程序时,shell环境读入你的键盘的输入给程序,将程序的输出结果打印到屏幕,如果出错将出错信息也打印到屏幕上。
那么有时我们需要从文件中获取信息,或者希望将输出结果或出错信息保存到文件怎么办呢?这时候就要用到输入,输出,出错的重定向。比如:

复制内容到剪贴板
代码:
dir > io.txt

其结果是将dir命令的输出重定向到了io.txt文件,打开io.txt文件就能看到我们单独使用dir时在屏幕上显示的一样的结果。同样的道理,我们可以将输入重定向,比如:

复制内容到剪贴板
代码:

more

这就将标准输入重定向到刚刚创建的io.txt文件,使它变为more的标准输入,然后more命令将内容分页显示出来。
如果要重定向出错信息就要用‘2>’这个符号(用于类Unix系统)。除了上面所例举重定向方法,还有经常用到的就是“管道”,它将一个程序的输出作为另一个程序的输入,比如上面用到的例子我们可以用管道一步完成:

复制内容到剪贴板
代码:

dir|more

与上面分两步得到的结果是一样的,就是把dir的结果分页显示。

那么在Python语言中是如何处理,标准输入/输入及其重定向的呢?其实很简单,比如创建一个最简单的Python程序 hello.py:

复制内容到剪贴板
代码:

#testing stdout

print 'Hello World!'

运行hello.py就会在标准输出的屏幕上打印 Hello World!, 我们再编一个简单的标准输入的小程序 sayhi.py:

复制内容到剪贴板
代码:
#testing stdin

print 'Hi, %s!' % raw_input('Please enter your name:')

当你用键盘输入你的名字后,程序在屏幕上输出Hi,[你的名字]!, 这就是从标准输入:键盘获取信息,再输出到标准输出:屏幕的例子。
那么上面的例子中print 和 raw_input是如何与标准输入/输出流建立关系的呢?
其实Python程序的标准输入/输出/出错流定义在sys模块中,分别为: sys.stdin, sys.stdout, sys.stderr
上面的程序分别与下列的程序是一样的:

复制内容到剪贴板
代码:
import sys

sys.stdout.write('Hello World!')
复制内容到剪贴板
代码:
import sys

print 'Please enter your name:',
name=sys.stdin.readline()[:-1]
print 'Hi, %s!' % name

那么sys.stdin, sys.stdout, stderr到底是什么呢?我们在Python运行环境中输入以下代码:

复制内容到剪贴板
代码:

import sys
for f in (sys.stdin, sys.stdout, sys.stderr): print f

输出为:

复制内容到剪贴板
代码:

...
', mode 'r' at 892210>
', mode 'w' at 892270>
', mode 'w at 8922d0>

由此可以看出stdin, stdout, stderr在Python中无非都是文件属性的对象,他们在Python启动时自动与Shell环境中的标准输入,输出,出错关联。
而Python程序的在Shell中的I/O重定向与本文开始时举的DOS命令的重定向完全相同,其实这种重定向是由Shell来提供的,与Python本身并无关系。那么我们是否可以在Python程序内部将stdin,stdout,stderr读写操作重定向到一个内部对象呢?答案是肯定的。
Python提供了一个StringIO模块来完成这个设想,比如:

复制内容到剪贴板
代码:

from StringIO import StringIO
import sys
buff =StringIO()

temp = sys.stdout                            #保存标准I/O流
sys.stdout = buff                               #将标准I/O流重定向到buff对象
print 42, 'hello', 0.001

sys.stdout =temp                               #恢复标准I/O流
buff.getvaue()

结果:

复制内容到剪贴板
代码:

42, 'hello', 0.001

而Python 2.0以后的版本更是简单明了,上面的代码可以简化到:

复制内容到剪贴板
代码:
print   >> buff , 42, 'hello', 0.001