一、概述
开发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来实现其他的处理方式。