0

I am looking for a way to redirect output from Standard output to a file without a delay . Writing to a file seems ok using following code :

import time  
import sys,os
def test():
    j = 1
    while j < 10 :
        time.sleep(1)
        print("Python is good .Iteration ",j )
        j +=1

if __name__ == "__main__":
    myFile= open( "logFile.log", "w", 0 )
    sys.stdout= myFile
    test()

However , This only writes to the file on completion of the code i.e. after 9th iteration . I want to know if we can write data to file before completion of whole code and see the output in the file by maybe doing a tail -f logFile.log

Thanks in advance

paarth batra
  • 1,392
  • 4
  • 29
  • 53
  • @AlexThornton the `print("Python is good .Iteration ",j )` will write to the file because he's redirected the `sys.stdout` prior to launching `test()` :) – Torxed Feb 24 '14 at 07:44

4 Answers4

3

A simple solution is to add a -u option for python command to force unbuffered stdin, stdout and stderr.

python -u myscript.py
hago
  • 1,700
  • 2
  • 16
  • 18
2

This is because nothing is flushing the output buffer. Try adding this to your code once in a while:

sys.stdout.flush()

It's not perfect but should work.
Also it's early in the morning and there might be a better solution than this but i came up with this idea just now:

class log():
    def __init__(self, file):
        self.file = open(file, 'r', 0)

    def write(self, what):
        self.file.write(what)
        self.file.flush()

    def __getattr__(self, attr):
       return getattr(self.file, attr)

sys.stdout = log()

Haha, and yea that's the marked solution in the dupe, so i'll point the scores to that post :P beaten to it by 30 sec :)

Torxed
  • 22,866
  • 14
  • 82
  • 131
  • Hi Torxed , I was looking for something where I can see the output of data as soon as it writes and not at the end of program . i already tried flush() but seems we can only see the data on file at the end of program ? – paarth batra Feb 24 '14 at 08:45
  • @paarthbatra After each `print(...)` do `sys.stdout.flush()` :) – Torxed Feb 24 '14 at 08:46
  • @Alex Thornton sys.stdout.flush() works as intended issue was i was using this in windows and cant see tail like output in it . on linux tail works . Thanks for the answers however i was looking to make a Qt TextEdit as a standard Output for this data and keep it as buffereing , I mean show data without delay . Thanks :) – paarth batra Feb 24 '14 at 09:00
2

For every iteration, you must add this.

sys.stdout.flush()

This flushes the output buffer, and does the equivalent of opening and closing the file so the changes are appended.

However, I don't see what's wrong with it appending all the data at the end, as you still get the same result and you won't be able to access that file externally while that program is using it anyway.

anon582847382
  • 19,907
  • 5
  • 54
  • 57
  • What i sad. Also, "what's wrong" is that the data can be lost depending on how the process dies and the file-system handles it. And `flush()` has nothing to do with opening/closing a filehandle. FYI. But i assume you're refering to the fact that it will output the data to the file just as if you would close it manually? Well that's because `close()` flushes, so close is the equivilant of flush not the other way around :) – Torxed Feb 24 '14 at 07:50
  • That was my question as if how to access the file while program is still writing to it externally as we do it in linux , tail -f . – paarth batra Feb 24 '14 at 08:37
0

The output is buffered since it's more efficient to write larger chunks of data to a file. You can either flush() the buffer explicitly or you use sys.stderr as output. A third approach, which might be a better solution for a larger project is, to use the logging module included in python. It allows you to raise messages with different log levels and to redirect these log levels differently, including directly flushing to a file.

Denis
  • 136
  • 6