开发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