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

当前回答

我能够破解这个使用以下方法。它将使用这个打印函数而不是内置的打印函数,并将内容保存到一个文件中。

from __future__ import print_function
import builtins as __builtin__

log = open("log.txt", "a")

def print(*args):
    newLine = ""
    for item in args:
        newLine = newLine + str(item) + " "
    newLine = (
        newLine
        + """
"""
    )
    log.write(newLine)
    log.flush()
    __builtin__.print(*args)
    return

其他回答

这是我用来打印到文件/日志的另一种方法…修改内置的打印函数,使其记录到具有当前时间戳的temp目录中的文件,并打印到stdout。在脚本中这样做的唯一真正好处是不需要去修改现有的打印语句。

print('test')
test

复制原始打印函数到新变量

og_print = print
og_print('test2')
test2

覆盖现有的打印功能

def print(*msg):
    '''print and log!'''
    # import datetime for timestamps
    import datetime as dt
    # convert input arguments to strings for concatenation
    message = []
    for m in msg:
        message.append(str(m))
    message = ' '.join(message)
    # append to the log file
    with open('/tmp/test.log','a') as log:
        log.write(f'{dt.datetime.now()} | {message}\n')
    # print the message using the copy of the original print function to stdout
    og_print(message)
print('test3')
test3

显示文件

cat /tmp/test.log
2022-01-25 10:19:11.045062 | test3

删除文件

rm /tmp/test.log

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)

不要使用打印,使用日志记录

您可以更改sys。Stdout指向文件,但这是一种相当笨拙且不灵活的处理此问题的方法。不要使用print,而是使用logging模块。

使用日志记录,您可以像打印stdout一样进行打印,也可以将输出写入文件。您甚至可以使用不同的消息级别(关键、错误、警告、信息、调试),例如,只将主要问题打印到控制台,但仍然将次要代码操作记录到文件中。

一个简单的例子

导入日志记录,获取日志记录器,并设置处理级别:

import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG) # process everything, even if everything isn't printed

如果你想打印到标准输出:

ch = logging.StreamHandler()
ch.setLevel(logging.INFO) # or any other level
logger.addHandler(ch)

如果你也想写入一个文件(如果你只想写入一个文件,跳过最后一部分):

fh = logging.FileHandler('myLog.log')
fh.setLevel(logging.DEBUG) # or any level you want
logger.addHandler(fh)

然后,无论你在哪里使用打印,请使用记录器方法之一:

# print(foo)
logger.debug(foo)

# print('finishing processing')
logger.info('finishing processing')

# print('Something may be wrong')
logger.warning('Something may be wrong')

# print('Something is going really bad')
logger.error('Something is going really bad')

要了解关于使用更高级日志功能的更多信息,请阅读Python文档中的优秀日志教程。

我在过去用来输出一些字典的东西如下:

# sample dictionary
the_dict = {'a': 'no', 'c': 'yes', 'b': 'try again'}

# path to output to
dict_path = "D:/path.txt"

# script to output file
with open(dict_path, "w") as f:
    for idx, data in the_dict.items():
        print(idx, data, file=f)

输出的文件如下所示:

a no
c yes
b try again

你可以用file参数重定向打印(在python2中有>>操作符代替)。

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