開發Web程序時,一般會採用本地服務器進行調試,但若是代碼有變更,就須要重啓服務器。開發過程當中修改代碼是常常的事,不斷地重啓服務器既麻煩又耗時。所以爲了不這種笨拙的行爲,在流行的Web框架中,都提供了 模塊自動重載 的功能:不用重啓服務器,自動從新加載有變更的模塊。python
自動 的方式有不少,具體跟Web框架的實現強相關。像web.py中就是經過每次處理請求時都嘗試重載來模擬自動,而flask中則是使用獨立線程來完成的。簡單起見,本文的測試代碼中採用while循環(獨立進程)來實現自動。git
遍歷已經加載的全部模塊,查看每一個模塊的對應文件的最近修改時間,若是時間有變化,則從新加載該模塊。github
#!/usr/bin/env python # -*- coding: utf-8 -*- """Reload modules if modified usage: python reloader.py [test_module_name] """ import sys import os mtimes = {} def do_reload(handler=None): """Reload modules if modified """ for module in sys.modules.values(): # get filename filename = getattr(module, '__file__', None) if not (filename and os.path.isfile(filename)): continue # handle python file extensions # for more details about this topic, # see http://stackoverflow.com/questions/8822335/what-does-python-file-extensions-pyc-pyd-pyo-stand-for if filename[-4:] in ('.pyc', '.pyo', '.pyd'): filename = filename[:-1] # get the '.py' file # get the time of most recent content modification try: mtime = os.stat(filename).st_mtime except OSError: continue # reload `module` if it's modified old_time = mtimes.get(module) if old_time is None: # the first time in this function, just record mtime mtimes[module] = mtime elif old_time < mtime: # `module` is modified try: reload(module) mtimes[module] = mtime if handler: # call handler() if necessary handler(module) except ImportError: pass if __name__ == '__main__': if len(sys.argv) != 2: sys.stderr.write(__doc__) sys.exit(1) test_module_name = sys.argv[1] import importlib try: importlib.import_module(test_module_name) except ImportError, e: print(str(e)) sys.exit(1) import time def handler(module): print(dir(module)) print('start reloading module `%s` automatically...' % test_module_name) while True: try: do_reload(handler) time.sleep(2) except KeyboardInterrupt: break
$ touch testmod.py $ python reloader.py testmod start reloading module `testmod` automatically...
$ vi testmod.py ...
一旦對testmod.py有修改保存,終端1中會當即打印出模塊testmod的當前全部屬性。固然,也能夠修改handler來實現其餘的處理方式。web
(1)web.py的Reloaderflask