6

There are times when I want my program to write something on the terminal for immediate inspection and on a file for later use, so I write something like:

print "output"
file.write("output")   #the same output as the previous line

Is it possible, with python 2.6 or 7, to do it in another, maybe smarter, way?

manlio
  • 18,345
  • 14
  • 76
  • 126
mattiav27
  • 655
  • 2
  • 9
  • 27
  • Are you asking if there is a function that outputs to both file and terminal in one call? – Cory Kramer Mar 07 '14 at 13:04
  • `print "output"` is more like `file.write("output"+"\n")`... `print` adds a trailing newline. Just a detail, mind you. – isedev Mar 07 '14 at 13:04

2 Answers2

16

You could wrap that into a function:

>>> def fprint(output):
...    print output
...    with open("somefile.txt", "a") as f:
...        f.write("{}\n".format(output))

If this is logging information, you should look into the logging module. Using the logging module you can easily configure and control multiple destinations for the logging events.

Example from the logging cookbook:

import logging

# set up logging to file - see previous section for more details
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
                    datefmt='%m-%d %H:%M',
                    filename='/temp/myapp.log',
                    filemode='w')
# define a Handler which writes INFO messages or higher to the sys.stderr
console = logging.StreamHandler()
console.setLevel(logging.INFO)
# set a format which is simpler for console use
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
# tell the handler to use this format
console.setFormatter(formatter)
# add the handler to the root logger
logging.getLogger('').addHandler(console)

# Now, we can log to the root logger, or any other logger. First the root...
logging.info('Jackdaws love my big sphinx of quartz.'

# Now, define a couple of other loggers which might represent areas in your
# application:

logger1 = logging.getLogger('myapp.area1')
logger2 = logging.getLogger('myapp.area2')

logger1.debug('Quick zephyrs blow, vexing daft Jim.') # Won't print, file only
logger1.info('How quickly daft jumping zebras vex.') # Printed and to file
logger2.warning('Jail zesty vixen who grabbed pay from quack.') # Printed and to file
logger2.error('The five boxing wizards jump quickly.') # Printed and to file.

The above example will write all messages with a logging level of logging.DEBUG or higher to a file called /temp/myapp.log. Messages with level logging.INFO are printed to sys.stderr. I highly advocate the use of this module for any logging purposes above simple debug prints.

EDIT: Had the wrong example!

msvalkon
  • 11,887
  • 2
  • 42
  • 38
0

Hopefully is not too late, here I go. This worked for me.

import sys
import logging

class Logger(object):
    def __init__(self, filename):
        self.terminal = sys.stdout
        self.log = open(filename, "a")
    def __getattr__(self, attr):
        return getattr(self.terminal, attr)
    def write(self, message):
        self.log.write(message)     
    def flush(self):
        self.log.flush()

Then, it can be used as

sys.stdout = Logger("file.txt")