0

Normally when I write stdout to a file, I do it like this.

import sys
sys.stdout = open(myfile, 'w')
print "This is in a file."

Now, this method looks ugly to me, and I've heard here and there that there is a better method. If so, what is this better method?

Vladimir Putin
  • 661
  • 1
  • 8
  • 18
  • 4
    Glad to see you on StackOverflow, mr. President. See this relevant/duplicate thread: http://stackoverflow.com/questions/4110891/python-how-to-simply-redirect-output-of-print-to-a-txt-file-with-a-new-line-crea – alecxe Jul 17 '14 at 03:11

3 Answers3

4

You can also make use of the fact that print can actually wrote to a file.

with open("file.txt", "w") as f:
    print("Hello World!", file=fd)

NB: This is Python 3.x Syntax only as print is a function in Python 3.x.

For Python 2.x you can however do:

from __future__ import print_function

Otherwise the same can be achieved with:

with open("file.txt", "w") as fd:
    print >> fd, "Hello World!"

See: print() from Python 3.x Docs.

James Mills
  • 18,669
  • 3
  • 49
  • 62
3

Print directly to the file, using either

with open(myfile, 'w') as fh:
    fh.write("This is in a file.\n")

or

with open(myfile, 'w') as fh:
    print >>fh, "This is in a file."

or

from __future__ import print_function
with open(myfile, 'w') as fh:
    print("This is in a file.", file=fh)
chepner
  • 497,756
  • 71
  • 530
  • 681
2

You can do it as shown in the other answers, but it gets kind of old specifying the output file in every statement. So I understand the urge to just redirect sys.stdout. But yes, the way you propose doing it is not as elegant as it could be. Adding proper error handling will make it even uglier. Fortunately, you can create a handy context manager to address these issues:

import sys, contextlib

@contextlib.contextmanager
def writing(filename, mode="w"):
    with open(filename, mode) as outfile:
        prev_stdout, sys.stdout = sys.stdout, outfile
        yield prev_stdout
        sys.stdout = prev_stdout

Usage:

with writing("filename.txt"):
     print "This is going to the file"
     print "In fact everything inside the with block is going to the file"
print "This is going to the console."

Note that you can use the as keyword to get the previous stdout, so you can still print to the screen inside the with block:

with writing("filename.txt") as stdout:
     print "This is going to the file"
     print >> stdout, "This is going to the screen"
     print "This is going to the file again"
kindall
  • 178,883
  • 35
  • 278
  • 309