Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here's an example of how this could be implemented using pyinotify (ie., on Linux).</p> <pre><code>from importlib import import_module class RestartingLauncher: def __init__(self, module_name, start_function, stop_function, path="."): self._module_name = module_name self._filename = '%s.py' % module_name self._start_function = start_function self._stop_function = stop_function self._path = path self._setup() def _setup(self): import pyinotify self._wm = pyinotify.WatchManager() self._notifier = pyinotify.ThreadedNotifier( self._wm, self._on_file_modified) self._notifier.start() # We monitor the directory (instead of just the file) because # otherwise inotify gets confused by editors such a Vim. flags = pyinotify.EventsCodes.OP_FLAGS['IN_MODIFY'] wdd = self._wm.add_watch(self._path, flags) def _on_file_modified(self, event): if event.name == self._filename: print "File modification detected. Restarting application..." self._reload_request = True getattr(self._module, self._stop_function)() def run(self): self._module = import_module(self._module_name) self._reload_request = True while self._reload_request: self._reload_request = False reload(self._module) getattr(self._module, self._start_function)() print 'Bye!' self._notifier.stop() def launch_app(module_name, start_func, stop_func): try: import pyinotify except ImportError: print 'Pyinotify not found. Launching app anyway...' m = import_module(self._module_name) getattr(m, start_func)() else: RestartingLauncher(module_name, start_func, stop_func).run() if __name__ == '__main__': launch_app('example', 'main', 'force_exit') </code></pre> <p>The parameters in the launch_app call are the filename (without the ".py"), the function to start execution and a function that somehow stops the execution.</p> <p>Here's a stupid example of an "app" that could be (re-)launched using the previous code:</p> <pre><code>run = True def main(): print 'in...' while run: pass print 'out' def force_exit(): global run run = False </code></pre> <p>In a typical application where you'd want to use this, you'd probably have a main loop of some sort. Here's a more real example, for a GLib/GTK+ based application:</p> <pre><code>from gi.repository import GLib GLib.threads_init() loop = GLib.MainLoop() def main(): print "running..." loop.run() def force_exit(): print "stopping..." loop.quit() </code></pre> <p>The same concept works for most other loops (Clutter, Qt, etc).</p> <p>Monitoring several code files (ie. all files that are part of the application) and error resilience (eg. printing exceptions and waiting in an idle loop until the code is fixed, then launching it again) are left as exercises for the reader :).</p> <p><em>Note: All code in this answer is released under the ISC License (in addition to Creative Commons).</em></p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload