python print 输出到txt_Python基础教程讲解——print输出重定向介绍

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

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

sys.stdout.write('Hello World')print('Hello World')

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

print(sys.stdout) # <_io.textiowrapper name="<stdout>" mode="w" encoding="UTF-8">print(sys.stdin) # <_io.textiowrapper name="<stdin>" mode="r" encoding="UTF-8">print(sys.stderr) # <_io.textiowrapper name="<stderr>" mode="w" encoding="UTF-8">print(sys.__stdout__) # <_io.textiowrapper name="<stdout>" mode="w" encoding="UTF-8">print(sys.__stdin__) # <_io.textiowrapper name="<stdin>" mode="r" encoding="UTF-8">print(sys.__stderr__) # <_io.textiowrapper name="<stderr>" 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打印的内容就从控制台搬到了文本上了,如下所示:

7c7c764a-ed36-4a17-9ae5-f3e867185cbd

如果只是临时向文件中打印内容,之后仍然会在控制台上打印的话,应该先将原始的控制台引用对象保存下来,之后将该引用恢复到sys.stdout中。如下所示:

__console__ = sys.stdout# redirection start# ...# redirection endsys.stdout = __console__

以上的实现方法并不优雅,典型的实现如下所示:

# 临时把标准输出重定向到一个文件,然后再恢复正常with open('redirect.txt', 'w') as f:    oldstdout = sys.stdout    sys.stdout = f    try:        help(__import__)    finally:        sys.stdout = oldstdoutprint("Hello World")
9f454567d2084fbf943431c68b9a7a1e

接下来介绍Pyhton上下文管理器redirect_stdout实现重定向的方法。contextlib.redirect_stdout在Python 3.4加入。如下所示:

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

当然,其实redirect_stdout的内在实现逻辑也仅是保存控制台的引用,而后恢复如此而已。于是我们可以实现自己的redirect_stdout上下文管理器。如下所示:

@contextlib.contextmanagerdef redirect_stdout(fileobj):    oldstdout = sys.stdout    sys.stdout = fileobj    try:        yield fileobj    finally:        sys.stdout = oldstdoutdef redirect4():    with open('redirect.txt', 'w') as f:        with redirect_stdout(f):            help(pow)    print("Hello World")

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值