如果只是向记录一下日志的话, 可以简单的
sys.stdout = open('log.txt', 'w')
深入一点了解的话
print
使用的是sys.stdout.write()
但是不能直接替换stdout.write = new_write
所以思路是构造一个新的打印类, 让这个类的方法都等于stdout类的方法
然后替换sys.stdout = new_out
代码如下
# coding=utf-8
class A(object):
def __init__(self):
self.test = 2
def write(self):
pass
import sys
a = A()
save_stdout = None
print dir(sys.stdout)
for item in dir(sys.stdout):
if not item.startswith('__'):
setattr(a, item, getattr(sys.stdout, item))
save_stdout = sys.stdout
sys.stdout = a
def new_write(str):
save_stdout.write('???')
save_stdout.write(str)
# 在这个地方设置write是因为上面遍历stdout的方法是设置了write, 这里要覆盖为我们自己的
a.write = new_write
print 'hello world'
这样写也会出现一些问题, 新定义的print
函数new_write
那里, 接收到的就已经是python的字符串格式
了, 即使是个字典, 在这里也已经转化为字符串了, 且全部为单引号, 如果把这个字符串传递给后台程序, 大多会造成json
解析出现问题, 所以如果要传递给其他程序, 最好在这里替换下引号line.replace('\'', '\"')
下面是一个比较完善的例子
import sys
new_stdout = type('MyStdout', (object, ), {})()
new_stderr = type('MyStderr', (object, ), {})()
def new_sys_stdout(line):
global old_stdout
old_stdout.write('stdout {}'.format(line))
def new_sys_stderr(line):
global old_stderr
old_stderr.write('stderr {}'.format(line))
for item in dir(sys.stdout):
if not item.startswith('__'):
setattr(new_stdout, item, getattr(sys.stdout, item))
for item in dir(sys.stderr):
if not item.startswith('__'):
setattr(new_stderr, item, getattr(sys.stderr, item))
old_stdout = sys.stdout
old_stderr = sys.stderr
new_stdout.write = new_sys_stdout
new_stderr.write = new_sys_stderr
sys.stdout = new_stdout
sys.stderr = new_stderr
print >> sys.stdout, "hello"
print >> sys.stderr, "hello"