13

Google App Engine の WebApp2 アプリケーションで次のコードを検討してください。

count = 0

class MyHandler(webapp2.RequestHandler):

    def get(self):

        global count
        count = count + 1
        print count

ページを更新するたびに、カウントが増加します。

私は、すべてのリクエストが新しいグローバル環境である PHP の世界から来ました。ここで起こっていることを理解しているのは、WebApp2 に wsgi 構成を使用しているため、Python は要求ごとに新しいプロセスを開始しないということです。一方、cgi 構成を使用していた場合、グローバル環境は PHP のように毎回再インスタンス化されます...

上記が正しいと仮定します(そうでない場合は、私を修正してください)...

  1. リクエストの存続期間中のみ持続するグローバル変数が必要なシナリオを処理するにはどうすればよいですか? RequestHandler クラスにインスタンス変数を配置することもできますが、メッセージ オブジェクトの格納などのためにグローバル変数を使用する、インポートするユーティリティ モジュールなどについてはどうでしょうか。
  2. すべての変数をリセットする、または環境の再インスタンス化を強制する何らかの手法はありますか?
  3. グローバル環境は無期限に存続しますか? それとも、ある時点で自動的にリセットされますか?
  4. この GAE 固有のものはありますか、それとも wsgi グローバル永続性はどのサーバー シナリオでも同じように機能しますか?

編集:

スレッドローカルを使用した試みは次のとおりです。

count = 0

mydata = threading.local()
mydata.count = 0

class MyHandler(webapp2.RequestHandler):

    def get(self):

        global count
        count = count + 1
        print count

        mydata.count = mydata.count + 1
        print mydata.count

これらもリクエスト間で増加します

4

3 に答える 3

17

あなたの理解は正しいです。リクエストの期間中持続する変数が必要な場合は、それらをグローバルにするべきではありません-としてアクセスされるRequestHandlerクラスのインスタンス変数にしますself.var。リクエストごとに新しいRequestHandlerがインスタンス化されるため、変数は必要な限り正確に保持されます。グローバル(リクエスト固有ではなく)スコープが本当に必要でない限り、グローバル変数は避けるのが最善です。

また、AppEngineアプリは複数のサーバーで実行されることに注意してください。グローバルは、同じサーバー内のリクエストにのみアクセスできます。

于 2011-11-18T01:50:22.860 に答える
5

状況の分析は正しいです。Python Web アプリは長時間実行されるプロセスです。Python インタープリターのスピンアップには長い時間がかかり、すべての要求が完了するわけではありません。

「リクエストごと」に異なるグローバル変数を作成することは完全に可能です。これは多くのフレームワークで行われており、人々はそれを気に入っているようです。これを行う方法は、サーバーによって異なります。ほとんどのサーバーは「リクエストごとに 1 つのスレッド」を使用しますが、GAE も同様だと思います。この場合、スレッドローカル変数を使用できます。この値がそのスレッドのリクエスト間で固執することが心配な場合は、リクエストの開始/終了にフックできる管理コードが必要になります。WSGI ミドルウェアは、WebApp2 フレームワークが適切な方法を提供しない場合に適しています。

これは単なる Python であり、リクエストは独自のスレッドで処理されます。そこから、やりたいことができます。Python には、すべてのグローバル変数をリセットするだけのものはありません。また、一般的に (特に GAE では) リクエストを処理するプロセスが毎回同じプロセスになるという保証はありません。あなたが何をしているか本当に知っています。

これを行うための優れたサポートを提供するフレームワークはすでにたくさんあるので、WebApp2 がそうでない場合は、他の場所を探すことをお勧めします。Python には多くのオプションがあり、それらの多くは GAE 上で実行されます。

于 2011-11-17T17:07:06.750 に答える
2

最初の質問の場合、webapp2.Request.registry機能を検討すると思います。リクエストの存続期間中にさまざまなモジュールが共有できるインスタンスを保存することは重要です。

一方、webapp2.WSGIApplication.registryも便利です。この場合、インスタンスはリクエスト間で存続し、アプリケーションの存続期間中にアプリが必要とするものすべてに共有(および再利用)できるため、グローバルスコープでインスタンスを作成する必要がありません。

于 2011-11-27T02:16:21.830 に答える