我想使用Python将打印重定向到一个.txt文件。我有一个for循环,它将打印每个.bam文件的输出,而我想将所有输出重定向到一个文件。所以我试着说:
f = open('output.txt','w')
sys.stdout = f
在我剧本的开头。但是,我在.txt文件中什么也没有得到。
我的剧本是:
#!/usr/bin/python
import os,sys
import subprocess
import glob
from os import path
f = open('output.txt','w')
sys.stdout = f
path= '/home/xxx/nearline/bamfiles'
bamfiles = glob.glob(path + '/*.bam')
for bamfile in bamfiles:
filename = bamfile.split('/')[-1]
print 'Filename:', filename
samtoolsin = subprocess.Popen(["/share/bin/samtools/samtools","view",bamfile],
stdout=subprocess.PIPE,bufsize=1)
linelist= samtoolsin.stdout.readlines()
print 'Readlines finished!'
那么问题是什么呢?除了sys。stdout还有其他方法吗?
我需要我的结果看起来像:
Filename: ERR001268.bam
Readlines finished!
Mean: 233
SD: 10
Interval is: (213, 252)
Python 2或Python 3 API参考:
Print (*objects, sep=' ', end='\n', file=sys. txt)stdout,冲洗= False)
file参数必须是一个具有write(string)方法的对象;如果不存在或为None,则sys。将使用Stdout。由于打印参数被转换为文本字符串,print()不能用于二进制模式的文件对象。对于这些,使用file.write(…)代替。
由于文件对象通常包含write()方法,您所需要做的就是将一个文件对象传递到它的参数中。
写入/覆盖到文件
with open('file.txt', 'w') as f:
print('hello world', file=f)
写入/追加到文件
with open('file.txt', 'a') as f:
print('hello world', file=f)
最明显的方法是打印到一个文件对象:
with open('out.txt', 'w') as f:
print('Filename:', filename, file=f) # Python 3.x
print >> f, 'Filename:', filename # Python 2.x
不过,重定向stdout对我也有用。对于像这样的一次性脚本,它可能很好:
import sys
orig_stdout = sys.stdout
f = open('out.txt', 'w')
sys.stdout = f
for i in range(2):
print('i = ', i)
sys.stdout = orig_stdout
f.close()
从Python 3.4开始,就有一个简单的上下文管理器可以在标准库中做到这一点:
from contextlib import redirect_stdout
with open('out.txt', 'w') as f:
with redirect_stdout(f):
print('data')
从shell本身向外部重定向是另一种选择,通常是更可取的:
./script.py > out.txt
其他问题:
你的脚本的第一个文件名是什么?我没有看到它被初始化。
我的第一个猜测是glob没有找到任何bamfile,因此for循环不会运行。检查文件夹是否存在,并在脚本中打印bamfiles。
同样,使用os.path.join和os.path.basename来操作路径和文件名。
如果重定向stdout对您的问题有效,Gringo Suave的回答很好地演示了如何进行重定向。
为了让它更简单,我使用上下文管理器创建了一个版本,使用with语句实现了简洁的通用调用语法:
from contextlib import contextmanager
import sys
@contextmanager
def redirected_stdout(outstream):
orig_stdout = sys.stdout
try:
sys.stdout = outstream
yield
finally:
sys.stdout = orig_stdout
要使用它,你只需要执行以下操作(源自Suave的例子):
with open('out.txt', 'w') as outfile:
with redirected_stdout(outfile):
for i in range(2):
print('i =', i)
当模块以您不喜欢的方式使用它时,它对于选择性地重定向打印非常有用。唯一的缺点(在许多情况下这是解决问题的关键)是,如果想要多个具有不同stdout值的线程,它就不起作用,但这需要一种更好、更通用的方法:间接模块访问。你可以在这个问题的其他答案中看到它的实现。