Detect the changes in a file and write them in a file
<p>I produced a script that detects the changes on files that are located in a specific directory. I'm trying to write all these changes to a <code>changes.txt</code> file. For this purpose I'm using the <code>sys.stdout = open('changes.txt','w')</code> instruction.</p>

<p>The problem is that whenever I run the script and change a file in the directory and save it, an empty file called <code>changes.txt</code> is created. This file is never written!</p>

<pre><code>#!/usr/bin/python
import time
import sys
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
sys.stdout = open('changes.txt','w')

class MyHandler(FileSystemEventHandler):
def on_modified(self, event):
    print "something happened!"


if __name__ == "__main__":
event_handler = MyHandler()
observer = Observer()
observer.schedule(event_handler, path='.', recursive=False)
observer.start()

try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    observer.stop()
</code></pre>

<p>I'd recommend something like</p>

<pre><code>#!/usr/bin/python

import time
import sys
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class MyHandler(FileSystemEventHandler):
    def __init__(self, f):
        self.f = f
    def on_modified(self, event):
        self.f.write("something happened!\n")
        self.f.flush()


if __name__ == "__main__":
    with open('changes.txt','w') as f:
        event_handler = MyHandler(f)
        observer = Observer()
        observer.schedule(event_handler, path='.', recursive=False)
        observer.start()

        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            observer.stop()
</code></pre>

<p>as you can see, the control over where your outputwill be written to has been handed to the caller (the one instanciating <code>MyHandler</code>) instead of the callee (<code>on_modified</code>).</p>

<p>This means you can also do</p>

<pre><code>event_handler = MyHandler(sys.stdout)
</code></pre>

<p>and see the output instead of the output being put into the file.</p>

<p>An additional benefit: using a context manager you can be sure the file is closed properly, even if errors occurr.</p>

python file