3

グローバル変数を持つDjango(Python)プログラムがあります:

g_variable = []

これは、値も変更するいくつかの関数です。

my_function()
    global g_variable 
    g_variable.append(some_value)

プログラムを複数回重複して呼び出し始めるまで、それはうまく機能しました.Djangoでは、Webページを複数回すばやくロードしたことを意味します. グローバル変数は個々の実行内でのみグローバルになると予想していましたが、そうではありません。1 回の実行で g_variable に追加された値は、次の実行で確認できます。

私にとってこれは、この変数をすべての関数に渡す必要があることを意味します。

my_function(non_g_variable)
    non_g_variable.append(some_value)
    return non_g_variable

と呼ばれる

non_g_variable = my_function(non_g_variable)

あれは正しいですか?すべてのコードを変更する前に、何かを見逃していないことを確認したいだけです。多くの余分な回線が追加され、コールが返されます。

4

4 に答える 4

3

他の回答やコメントが言うように、グローバル変数を取り除くためにコードを再設計する必要があります。次のようなもの:

class WebpageStructure(object):
    def __init__(self, html):
         # parse the html
         self.structure = self.parse(html)
    def contains_link(self):
         # figure it out using self.structure
         return ...

# in the view(s)
webpage = WebpageStructure(html_to_parse)
if webpage.contains_link():
    ...

ただし、次のオプションがあります。

  1. コードが常に単一のスレッドで実行される場合は、各実行の間に を設定g_variableすることで問題を解決できます。[]おそらく、各実行の開始を常にマークするトップレベル関数 (おそらく Django ビュー関数?) が 1 つあります。g_variableこの最上位関数でを再初期化する必要があります。

  2. コードがマルチスレッドで実行される場合、通常のグローバル変数は使用できません。同時スレッドは、同じグローバル変数を更新します。

    1と2に関して: シングルスレッドでDjangoサイトを実行するmanage.py runserver --nothreadingには、開発サーバーに使用します。サイトを apache/mod_wsgi でホストしている場合は、デーモン モードを使用してこれを制御できます。複数のシングルスレッド サイド バイ サイド プロセスを実行できることに注意してください。プロセスが分離されているため、グローバル変数を使用すると、そのシナリオで機能します。

    可能であれば、コードはどのプロセス/スレッド モデルでも動作するはずです。

  3. コードがマルチスレッドで実行され、g_variableリストの受け渡しを本当に避けたい場合は、スレッドローカル変数を使用できます。ドキュメンテーションここここ

例:

import threading
threadlocal = threading.local()

def mydjangoview(request):
    # In your top-level view function, initialize the list
    threadlocal.g_variable = []
    # Then call the functions that use g_variable
    foo()
    bar()

    # ... and then I guess you probably return a response?
    return Response(...)

def foo():
    threadlocal.g_variable.append(some_value)

def bar():
    threadlocal.g_variable.append(some_other_value)

その他のリンク:

于 2012-05-21T12:30:01.953 に答える
2

これが、Python でグローバル変数がどのように機能するかです。グローバルな状態は、Web アプリケーション サーバーが実行されている限り維持されます。

一般的な解決策は、関数をクラスに入れ、リクエストごとの状態をそのクラスに保存し、リクエストごとにそのクラスの新しいインスタンスを使用することです。

于 2012-05-21T12:31:02.017 に答える
1

定数を除いてグローバル変数を使用すると、ほとんどの場合エラーが発生しやすくなり、読みにくいコードが生成されることがよくあります。したがって、それは間違った概念です。引数を受け取り、それを変更して返すことは、グローバル変数をその場で変更するよりも、関数が何をしているかについてより明確です。

そうです、私は先に進んで receive-modify-return の概念を実装するか、誰かがあなたの問題に対する特別な「ジャンゴニック」ソリューションを提供するまで待ちます。

于 2012-05-21T12:23:39.080 に答える
0

問題は、キャッシュを実装することで解決できます(キャッシュを簡単に説明すると、セッション全体のグローバル変数です) 。

于 2012-05-21T12:43:33.720 に答える