除python
外,所有语言似乎都有问题/答案(至少我还没找到)
从这个问题Redirect stdout to a file in Python?我了解到,为了将屏幕上的所有输出重定向到我必须使用的文件:
import sys
some_list = ['elem1', 'elem2']
for elem in some_list:
sys.stdout = open(elem + '.log', 'w')
# Do lots of stuff that print messages.
print 'lots of stuff for', elem
print 'Code finished'
这会将所有输出存储到elemx.log
个文件中:
elem1.log
lots of stuff for elem1
elem2.log
lots of stuff for elem2
Code finished
我对这种方法有两个问题:
1-如何将最后一行打印的行(即:Code finished
)不存储在为上一个elem
创建的文件中?
2-如何在屏幕上显示存储的输出 ?
答案 0 :(得分:2)
包装很性感
import sys
class Logger(file):
def __init__(self,*a,**kw):
# copy original stdout to instance
self.stdout = sys.stdout
return super(Logger,self).__init__(*a,**kw)
def write(self,data):
self.stdout.write(data) # to screen
return super(Logger,self).write(data) #to file
def writelines(self,lines):
for line in lines: self.write(line)
def close(self):
# return it back
sys.stdout = self.stdout
some_list = ['elem1', 'elem2']
for elem in some_list:
with Logger("/tmp/1/{}.log".format(elem), "w") as sys.stdout:
# Do lots of stuff that print messages.
print 'lots of stuff for', elem
print 'Code finished'
结果
$ python2 out.py
Code finished
$ ls
elem1.log elem2.log out.py
酷副作用:
print 'this on screen'
with Logger("/tmp/1/main.log", "w") as sys.stdout:
print 'this on screen an in main.log'
with Logger("/tmp/1/sub.log", "w") as sys.stdout:
print 'this on screen, in man.log and in sub.log'
print 'only on screen again'
答案 1 :(得分:2)
因此,您可以使用自定义重定向类来模拟unix tee
功能:
import sys
import os
class OutputRedirect(object):
def __init__(self):
self.output_devices = []
def add_device(self,name):
self.output_devices.append(open(name,"w+"))
def remove_device(self,name):
idx = [f.name for f in self.output_devices].index(name)
self.output_devices.pop(idx)
def write(self,msg):
for device in self.output_devices:
device.write(msg)
def __del__(self):
for device in self.output_devices:
device.close()
def main():
outputs = OutputRedirect()
outputs.add_device("test.txt")
outputs.add_device("/dev/stdout")
sys.stdout = outputs
print "this is a test"
print "this is another test"
outputs.remove_device("test.txt")
print "this is not written to file"
if __name__ == "__main__":
main()
这将允许您拦截打印语句并使用它们执行您喜欢的操作。您甚至可以在消息中添加自定义标记,以指定它们应该转到哪些输出设备。但是,正如我在上面的评论中所说,logging
可能是更好的选择。
答案 2 :(得分:1)
要在标准输出上输出上一次,只需将sys.stdout分配给标准输出文件流。
import sys
some_list = ['elem1', 'elem2']
for elem in some_list:
sys.stdout = open(elem + '.log', 'w')
# Do lots of stuff that print messages.
print 'lots of stuff for', elem
sys.stdout = open("/dev/stdout", "w")
print 'Code finished'
对于第二个问题,我认为没有任何其他解决方案,而是打印两次,一次在标准输出上,另一次在档案上。
import sys
some_list = ['elem1', 'elem2']
for elem in some_list:
f = open(elem + '.log', 'w')
# Do lots of stuff that print messages.
print 'lots of stuff for '+ elem
f.write( 'lots of stuff for '+ elem)
print 'Code finished'
f.write( 'Code finished')
答案 3 :(得分:1)
这会产生预期的结果。
import sys
some_list = ['elem1', 'elem2']
for elem in some_list:
with open(elem + '.log', 'w') as f:
# Do lots of stuff that print messages.
f.write('lots of stuff for ' + elem)
print 'lots of stuff for', elem
print 'Code finished'
标准输出
lots of stuff for elem1
lots of stuff for elem2
Code finished
elem1.log
lots of stuff for elem1
elem2.log
lots of stuff for elem2