开发者社区> 千锋Python讲堂> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

Python基础教程讲解——print输出重定向介绍

简介: Python基础教程讲解——print输出重定向介绍
+关注继续查看

本期的Python基础教程给大家讲print输出相关知识点,敲黑板听课了!

Python中调试程序使用最多的是print(),在使用print()打印时事实上是调用了 sys.stdout.write()。不过print在把内容打印到控制台后,追加了一个换行符(linefeed)。以下例程中,print和sys.stdout.write()是等价的:

sys.stdout.write('Hello Worldn')
print('Hello World')
在Python中, sys.stdin、sys.stdout和sys.stderr分别对应解释器的标准输入、标准输出和标准出错流。在程序启动时,这些对象的初值由sys.stdin、sys.__stdout__和sys.__stderr__保存,比便于恢复标准流对象。如下所示:

print(sys.stdout) # <_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>
print(sys.stdin) # <_io.TextIOWrapper name='' mode='r' encoding='UTF-8'>
print(sys.stderr) # <_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>

print(sys.__stdout__) # <_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>
print(sys.__stdin__) # <_io.TextIOWrapper name='' mode='r' encoding='UTF-8'>
print(sys.__stderr__) # <_io.TextIOWrapper name='' mode='w' encoding='UTF-8'>
如果我们要把内容重定向到文本中去时,该如何操作呢?我们先看下普通的文本对象和标准输出对象的区别。如下所示:

print(dir(sys.stdout))
"""
['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__',
'__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__',
'__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__',
'__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable',
'_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors',
'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable',
'readline', 'readlines', 'reconfigure', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write',
'write_through', 'writelines']
"""
with open('redirect.txt', 'w') as f:

print(f) # <_io.TextIOWrapper name='redirect.txt' mode='w' encoding='cp1252'>
print(dir(f))
"""
['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', 
'__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', 
'__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', 
'__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
'__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', 
'_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 
'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 
'readline', 'readlines', 'reconfigure', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 
'write_through', 'writelines']
"""

可见两者都属于文件对象,其中所包含的方法也都相同,比如write、read等等。所以,如果把文件对象的引用赋值给sys.stdout,那么print调用的即为文件对象的write方法,这样就实现了重定向。其实在之前的Python基础教程中有跟大家讲古。代码如下所示:

with open('redirect.txt', 'w') as f:

sys.stdout = f
print("Hello World")

重定向后,print打印的内容就从控制台搬到了文本上了,如下所示:

Python基础教程讲解——print输出重定向介绍
如果只是临时向文件中打印内容,之后仍然会在控制台上打印的话,应该先将原始的控制台引用对象保存下来,之后将该引用恢复到sys.stdout中。如下所示:

console = sys.stdout

redirection start

...

redirection end

sys.stdout = console
以上的实现方法并不优雅,典型的实现如下所示:

临时把标准输出重定向到一个文件,然后再恢复正常

with open('redirect.txt', 'w') as f:

oldstdout = sys.stdout
sys.stdout = f
try:
    help(__import__)
finally:
    sys.stdout = oldstdout

print("Hello World")
Python基础教程讲解——print输出重定向介绍
接下来介绍Pyhton上下文管理器redirect_stdout实现重定向的方法。contextlib.redirect_stdout在Python 3.4加入。如下所示:

with open('redirect.txt', 'w') as f:

with contextlib.redirect_stdout(f):
    help(pow)

_
Python基础教程讲解——print输出重定向介绍
当然,其实redirect_stdout的内在实现逻辑也仅是保存控制台的引用,而后恢复如此而已。于是我们可以实现自己的redirect_stdout上下文管理器。如下所示:

@contextlib.contextmanager
def redirect_stdout(fileobj):

oldstdout = sys.stdout
sys.stdout = fileobj
try:
    yield fileobj
finally:
    sys.stdout = oldstdout

def redirect4():

with open('redirect.txt', 'w') as f:
    with redirect_stdout(f):
        help(pow)

print("Hello World")

更多的Python基础教程也会继续更新,大家有想学想看的内容也可以留言,我会整理出相关文章哈!

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Python编程:Python2.7环境下的中文文件读写
Python编程:Python2.7环境下的中文文件读写
0 0
Python编程:实现tail-n查看日志文件
Python编程:实现tail-n查看日志文件
0 0
Python编程:pickleDB库Redis的简易替代
pickleDB 是一个轻量简单的 key-value 存储器,操作和redis 很类似 可以作为一个不错的工具
0 0
Python编程:six库兼容Python 2 和 Python 3
six 它是一个专门用来兼容 Python 2 和 Python 3 的库
0 0
Python编程:使用cachy缓存数据
Python编程:使用cachy缓存数据
0 0
python编程之数字和字符串类型
python编程之数字和字符串类型
0 0
PennyLane | 用于量子计算机可微分编程的跨平台Python库
PennyLane | 用于量子计算机可微分编程的跨平台Python库
0 0
Python 技巧篇-用print打印输出但不换行方法
Python 技巧篇-用print打印输出但不换行方法
0 0
python文档:开始进入编程(在前面的基础上)
python文档:开始进入编程(在前面的基础上)
0 0
+关注
千锋Python讲堂
Python忠实粉!从业Python已有6年!希望在这里跟大家一起分享我的经验和同伴交流!
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Python 脚本速查手册
立即下载
Python系列直播第一讲——Python中的一切皆对象
立即下载
Python第五讲——关于爬虫如何做js逆向的思路
立即下载