質問

私は現在フラスコで遊んでいますが、デバッグメカニズムがどのように機能しているかを理解できません。アプリケーションでpythonファイルを保存する場合、より正確にするために、サーバーを再起動する必要はありません。リクエストを行うと自動的にロードされます。それで、私の質問は、ランニングプログラムがそれが変更されたことをどのように知っており、その変更に応答するのですか?

役に立ちましたか?

解決

FlaskはWerkzugの基礎を使用しています run_with_reloader 関数(にあります serving.py)...それ自体を使用しています restart_with_reloaderreloader_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

他のヒント

内蔵 reload() 関数はあなたのためにこれを行うことができます。この関数は、フラスコがコードをリロードするために行うことの背後にある可能性があります(何らかの方法でディスク上で変更されたことに気付いた後)。

質問 Pythonモジュールをアンロード(リロード)するにはどうすればよいですか? これに関する詳細情報があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top