如何将'print'输出重定向到文件?

306 投票
15 回答
915668 浏览
提问于 2025-04-17 00:08

我想用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)

15 个回答

61

Python 2Python 3 的API参考:

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=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)
104

你可以通过使用 file 参数来改变打印输出的地方(在 Python 2 中是用 >> 操作符来实现的)。

f = open(filename,'w')
print('whatever', file=f) # Python 3.x
print >>f, 'whatever'     # Python 2.x

在大多数情况下,直接把内容写入文件会更好。

f.write('whatever')

或者,如果你有几个想要打印的内容,并且希望它们之间有空格,比如 print 的效果:

f.write(' '.join(('whatever', str(var2), 'etc')))
450

最简单的方法就是把内容打印到一个文件对象里:

with open('out.txt', 'w') as f:
    print('Filename:', filename, file=f)  # Python 3.x
    # print >> f, 'Filename:', filename   # Python 2.x

不过,把输出重定向到其他地方也可以用,这对于像这样的临时脚本来说应该没问题:

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')

另外,还有一种方法是直接从命令行重定向,这通常更好:

./script.py > out.txt

其他问题:

你的脚本里第一个文件名是什么?我没看到它被初始化。

我猜测可能是glob没有找到任何bam文件,所以for循环没有执行。检查一下文件夹是否存在,并在你的脚本中打印出bam文件。

另外,使用os.path.join和os.path.basename来处理路径和文件名。

撰写回答