Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python output on both console and file

I'm writing a code to analyze PDF file. I want to display the output on the console as well as to have a copy of the output in a file, I used this code save the output in a file:

import sys
sys.stdout = open('C:\\users\\Suleiman JK\\Desktop\\file.txt',"w")
print "test"

but could I display the output into console as well but without using classes because I'm not good with them?

like image 588
user3737563 Avatar asked Jun 07 '26 20:06

user3737563


2 Answers

(This answer uses Python 3 and you will have to adapt it if you prefer Python 2.)

Start by importing the Python logging package (and sys for accessing the standard output stream):

import logging
import sys

In your entry point, set up a handler for both the standard output stream and your output file:

targets = logging.StreamHandler(sys.stdout), logging.FileHandler('test.log')

and configure the logging package to output only the message without the log level:

logging.basicConfig(format='%(message)s', level=logging.INFO, handlers=targets)

Now you can use it:

>>> logging.info('testing the logging system')
testing the logging system
>>> logging.info('second message')
second message
>>> print(*open('test.log'), sep='')
testing the logging system
second message
like image 169
Adam Avatar answered Jun 10 '26 11:06

Adam


sys.stdout can point to any object that has a write method, so you can create a class that writes to both a file and the console.

import sys

class LoggingPrinter:
    def __init__(self, filename):
        self.out_file = open(filename, "w")
        self.old_stdout = sys.stdout
        #this object will take over `stdout`'s job
        sys.stdout = self
    #executed when the user does a `print`
    def write(self, text): 
        self.old_stdout.write(text)
        self.out_file.write(text)
    #executed when `with` block begins
    def __enter__(self): 
        return self
    #executed when `with` block ends
    def __exit__(self, type, value, traceback): 
        #we don't want to log anymore. Restore the original stdout object.
        sys.stdout = self.old_stdout

print "Entering section of program that will be logged."
with LoggingPrinter("result.txt"):
    print "I've got a lovely bunch of coconuts."
print "Exiting logged section of program."

Result:

Console:

Entering section of program that will be logged.
I've got a lovely bunch of coconuts.
Exiting logged section of program.

result.txt:

I've got a lovely bunch of coconuts.

This method may be preferable to codesparkle's in some circumstances, because you don't have to replace all your existing prints with logging.info. Just put everything you want logged into a with block.

like image 42
Kevin Avatar answered Jun 10 '26 10:06

Kevin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!