Python output on both console and file

梦想的初衷 提交于 2020-01-17 15:06:17

问题


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?


回答1:


You could make a function which prints both to console and to file. You can either do it by switching stdout, e.g. like this:

def print_both(file, *args):
    temp = sys.stdout #assign console output to a variable
    print ' '.join([str(arg) for arg in args]) 
    sys.stdout = file 
    print ' '.join([str(arg) for arg in args])
    sys.stdout = temp #set stdout back to console output

or by using file write method (I suggest using this unless you have to use stdout)

def print_both(file, *args):
    toprint = ' '.join([str(arg) for arg in args])
    print toprint
    file.write(toprint)

Note that:

  1. The file argument passed to the function must be opened outside of the function (e.g. at the beginning of the program) and closed outside of the function (e.g. at the end of the program). You should open it in append mode.
  2. Passing *args to the function allows you to pass arguments the same way you do to a print function. So you pass arguments to print...

...like this:

print_both(open_file_variable, 'pass arguments as if it is', 'print!', 1, '!')

Otherwise, you'd have to turn everything into a single argument i.e. a single string. It would look like this:

 print_both(open_file_variable, 'you should concatenate'+str(4334654)+'arguments together')

I still suggest you learn to use classes properly, you'd benefit from that very much. Hope this helps.




回答2:


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.




回答3:


(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


来源:https://stackoverflow.com/questions/24204898/python-output-on-both-console-and-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!