306 votes

Comment rediriger la sortie 'print' vers un fichier ?

Je veux rediriger l'impression vers un fichier .txt en utilisant Python. J'ai un for boucle, qui print la sortie pour chacun de mes fichiers .bam alors que je veux rediriger todo dans un seul fichier. J'ai donc essayé de mettre :

f = open('output.txt','w')
sys.stdout = f

au début de mon script. Cependant, je n'obtiens rien dans le fichier .txt. Mon script est :

#!/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!'

Alors quel est le problème ? Un autre moyen que celui-ci sys.stdout ?

Je veux que mon résultat ressemble à :

Filename: ERR001268.bam
Readlines finished!
Mean: 233
SD: 10
Interval is: (213, 252)

2voto

Arjun G Perambra Points 1152

Je parviens à résoudre ce problème en utilisant la méthode suivante. Il utilisera cette fonction d'impression au lieu de la fonction d'impression intégrée et enregistrera le contenu dans un fichier.

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

0voto

Jerome Points 1675

La modification de la valeur de sys.stdout change la destination de tous les appels à l'impression. Si vous utilisez une autre méthode pour changer la destination de l'impression, vous obtiendrez le même résultat.

Votre problème est ailleurs :

  • cela pourrait être dans le code que vous avez supprimé pour votre question (d'où vient le nom de fichier pour l'appel à l'ouverture ?)
  • il se peut aussi que vous n'attendiez pas que les données soient vidées : si vous imprimez sur un terminal, les données sont vidées après chaque nouvelle ligne, mais si vous imprimez dans un fichier, elles ne sont vidées que lorsque le tampon stdout est plein (4096 octets sur la plupart des systèmes).

0voto

Shawn Points 591

Dans python 3, vous pouvez réassigner print :

#!/usr/bin/python3

def other_fn():
    #This will use the print function that's active when the function is called
    print("Printing from function")

file_name = "test.txt"
with open(file_name, "w+") as f_out:
    py_print = print #Need to use this to restore builtin print later, and to not induce recursion

    print = lambda out_str : py_print(out_str, file=f_out)

    #If you'd like, for completeness, you can include args+kwargs
    print = lambda *args, **kwargs : py_print(*args, file=f_out, **kwargs)

    print("Writing to %s" %(file_name))

    other_fn()  #Writes to file

    #Must restore builtin print, or you'll get 'I/O operation on closed file'
    #If you attempt to print after this block
    print = py_print

print("Printing to stdout")
other_fn() #Writes to console/stdout

Notez que le imprimer de other_fn ne commute que les sorties car imprimer est réaffecté dans la portée globale. Si nous assignons imprimer à l'intérieur d'une fonction, le imprimer sur other_fn n'est normalement pas affecté. On peut utiliser le mondial mot-clé si nous voulons affecter tous les imprimer appels :

import builtins

def other_fn():
    #This will use the print function that's active when the function is called
    print("Printing from function")

def main():
    global print #Without this, other_fn will use builtins.print
    file_name = "test.txt"
    with open(file_name, "w+") as f_out:

        print = lambda *args, **kwargs : builtins.print(*args, file=f_out, **kwargs)

        print("Writing to %s" %(file_name))

        other_fn()  #Writes to file

        #Must restore builtin print, or you'll get 'I/O operation on closed file'
        #If you attempt to print after this block
        print = builtins.print

    print("Printing to stdout")
    other_fn() #Writes to console/stdout

Personnellement, je préférerais éviter l'obligation d'utiliser l'option print en intégrant le descripteur de fichier de sortie dans une nouvelle fonction :

file_name = "myoutput.txt"
with open(file_name, "w+") as outfile:
    fprint = lambda pstring : print(pstring, file=outfile)
    print("Writing to stdout")
    fprint("Writing to %s" % (file_name))

-2voto

ishiry ish Points 1

Quelque chose pour étendre la fonction print pour les boucles

x = 0
while x <=5:
    x = x + 1
    with open('outputEis.txt', 'a') as f:
        print(x, file=f)
    f.close()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X