一、概述
開發Web程式時,通常會採用本地伺服器進行除錯,但如果程式碼有變動,就需要重啟伺服器。開發過程中修改程式碼是經常的事,不斷地重啟伺服器既麻煩又耗時。因此為了避免這種笨拙的行為,在流行的Web框架中,都提供了 模組自動過載 的功能:不用重啟伺服器,自動重新載入有變動的模組。
自動 的方式有很多,具體跟Web框架的實現強相關。像web.py中就是通過每次處理請求時都嘗試過載來模擬自動,而flask中則是使用獨立執行緒來完成的。簡單起見,本文的測試程式碼中採用while迴圈(獨立程式)來實現自動。
二、思路
遍歷已經載入的所有模組,檢視每個模組的對應檔案的最近修改時間,如果時間有變化,則重新載入該模組。
三、實現
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#!/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 |
四、測試
1、開啟自動過載(終端1)
1 2 3 |
$ touch testmod.py $ python reloader.py testmod start reloading module `testmod` automatically... |
2、修改模組(終端2)
1 2 |
$ vi testmod.py ... |
3、檢視實時輸出(終端1)
一旦對testmod.py有修改儲存,終端1中會立即列印出模組testmod的當前所有屬性。當然,也可以修改handler來實現其他的處理方式。