Mar*_*riy 6 python dynamic flask
我正在玩Flask,我无法弄清楚调试机制是如何工作的.更准确地说,当我使用我的应用程序保存python文件时,我不需要重新启动服务器,它会在我发出请求时自动加载.所以我的问题是正在运行的程序如何知道它已被更改并响应这些更改?
烧瓶使用Werkzug的底层run_with_reloader
函数(发现serving.py
)...这是本身使用restart_with_reloader
,并reloader_loop
在同一个文件之前创建功能.
run_with_reloader
产生另一个python进程(再次使用传递给第一个的所有相同参数运行Werkzug),这个新进程使用该thread
模块生成一个运行服务器函数的新线程或子进程.然后运行reloader_loop
并等待.
reloader_loop
只需循环遍历已导入的所有模块并获取其上次修改日期.然后按指定的时间间隔(默认为1秒),它会再次检查所有文件以查看它们是否已被修改.如果有,则当前运行的(从属)Werkzug进程以退出代码3退出(终止).一旦退出,它启动的线程或子进程(实际上正在进行工作)也将终止.在主过程检查,看是否退出代码为3.如果是,它产生一个新的从子,就像以前那样.否则,它以相同的退出代码退出.
这是参考的代码:
def reloader_loop(extra_files=None, interval=1):
"""When this function is run from the main thread, it will force other
threads to exit when any modules currently loaded change.
Copyright notice. This function is based on the autoreload.py from
the CherryPy trac which originated from WSGIKit which is now dead.
:param extra_files: a list of additional files it should watch.
"""
def iter_module_files():
for module in sys.modules.values():
filename = getattr(module, '__file__', None)
if filename:
old = None
while not os.path.isfile(filename):
old = filename
filename = os.path.dirname(filename)
if filename == old:
break
else:
if filename[-4:] in ('.pyc', '.pyo'):
filename = filename[:-1]
yield filename
mtimes = {}
while 1:
for filename in chain(iter_module_files(), extra_files or ()):
try:
mtime = os.stat(filename).st_mtime
except OSError:
continue
old_time = mtimes.get(filename)
if old_time is None:
mtimes[filename] = mtime
continue
elif mtime > old_time:
_log('info', ' * Detected change in %r, reloading' % filename)
sys.exit(3)
time.sleep(interval)
def restart_with_reloader():
"""Spawn a new Python interpreter with the same arguments as this one,
but running the reloader thread.
"""
while 1:
_log('info', ' * Restarting with reloader...')
args = [sys.executable] + sys.argv
new_environ = os.environ.copy()
new_environ['WERKZEUG_RUN_MAIN'] = 'true'
# a weird bug on windows. sometimes unicode strings end up in the
# environment and subprocess.call does not like this, encode them
# to latin1 and continue.
if os.name == 'nt':
for key, value in new_environ.iteritems():
if isinstance(value, unicode):
new_environ[key] = value.encode('iso-8859-1')
exit_code = subprocess.call(args, env=new_environ)
if exit_code != 3:
return exit_code
def run_with_reloader(main_func, extra_files=None, interval=1):
"""Run the given function in an independent python interpreter."""
if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
thread.start_new_thread(main_func, ())
try:
reloader_loop(extra_files, interval)
except KeyboardInterrupt:
return
try:
sys.exit(restart_with_reloader())
except KeyboardInterrupt:
pass
Run Code Online (Sandbox Code Playgroud)