设为首页 收藏本站
查看: 1344|回复: 0

[经验分享] Python 标准输出 sys.stdout 重定向

[复制链接]

尚未签到

发表于 2015-4-28 08:22:35 | 显示全部楼层 |阅读模式
  本文环境:Python 2.7
  使用 print obj 而非 print(obj)
  

一些背景

sys.stdout 与 print
  当我们在 Python 中打印对象调用 print obj 时候,事实上是调用了 sys.stdout.write(obj+'\n')
  print 将你需要的内容打印到了控制台,然后追加了一个换行符
  print 会调用 sys.stdout 的 write 方法
  以下两行在事实上等价:



sys.stdout.write('hello'+'\n')
print 'hello'
sys.stdin 与 raw_input
  当我们用 raw_input('Input promption: ') 时,事实上是先把提示信息输出,然后捕获输入
  以下两组在事实上等价:



hi=raw_input('hello? ')
print 'hello? ', #comma to stay in the same line
hi=sys.stdin.readline()[:-1] # -1 to discard the '\n' in input stream
  

从控制台重定向到文件
  原始的 sys.stdout 指向控制台
  如果把文件的对象的引用赋给 sys.stdout,那么 print 调用的就是文件对象的 write 方法



f_handler=open('out.log', 'w')
sys.stdout=f_handler
print 'hello'
# this hello can't be viewed on concole
# this hello is in file out.log
  记住,如果你还想在控制台打印一些东西的话,最好先将原始的控制台对象引用保存下来,向文件中打印之后再恢复 sys.stdout



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

sys.stdout=__console__
同时重定向到控制台和文件
  如果我们希望打印的内容一方面输出到控制台,另一方面输出到文件作为日志保存,那么该怎么办?
  将打印的内容保留在内存中,而不是一打印就将 buffer 释放刷新,那么放到一个字符串区域中会怎样?



a=''
sys.stdout=a
print 'hello'
  OK,上述代码是无法正常运行的



Traceback (most recent call last):
File ".\hello.py", line xx, in
print 'hello'
AttributeError: 'str' object has no attribute 'write'
  错误很明显,就是上面强调过的,在尝试调用 sys.stdout.write() 的时候,发现没有 write 方法
  另外,这里之所以提示 attribute error 而不是找不到函数等等,我猜想是因为 python 将对象/类的函数指针记录作为对象/类的一个属性来对待,只是保留了函数的入口地址
  既然这样,那么我们必须给重定向到的对象实现一个 write 方法:



import sys
class __redirection__:
def __init__(self):
self.buff=''
self.__console__=sys.stdout
def write(self, output_stream):
self.buff+=output_stream
def to_console(self):
sys.stdout=self.__console__
print self.buff
def to_file(self, file_path):
f=open(file_path,'w')
sys.stdout=f
print self.buff
f.close()
def flush(self):
self.buff=''
def reset(self):
sys.stdout=self.__console__

if __name__=="__main__":
# redirection
r_obj=__redirection__()
sys.stdout=r_obj
# get output stream
print 'hello'
print 'there'
# redirect to console
    r_obj.to_console()
# redirect to file
r_obj.to_file('out.log')
# flush buffer
    r_obj.flush()
# reset
r_obj.reset()
  同样的,sys.stderr, sys.stdin 也都可以被重定向到多个地址,举一反三的事情就自己动手实践吧

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-61356-1-1.html 上篇帖子: python version 2.7 required,which was not found in the registry 下篇帖子: python __new__ 与__init__函数
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表