1

私はこの一般的な構造を持ついくつかのコードを持っています:

def runSolver():
    global a
    global b
    while (condition) :
        # do some stuff
        recalculateIntermediateParameters()
        # do more stuff
    return result

def recalculateIntermediateParameters():
    # read globals
    # calculate
    return recalculatedParameter

# main
if __name__="__main__":
    runSolver()

これが最良の実装であるかどうか疑問に思っています。たとえば、グローバルを関数で宣言するのは悪い習慣ですか? Java では、グローバル変数は関数定義の外で宣言するのが最適です。

私の考えでは、これは構文的に「より良い」だろうということでした:

def runSolver():
    a = foo
    b = bar
    # do some stuff
    return result

def recalculateIntermediateParameters(a, b):
    # do some stuff
    return recalculatedParameter

しかし、 と が関数によって操作されずに読み取られるだけの場合aはどうなるでしょうb? それはグローバルな配置に影響しますか? さらに、とが長いリストの場合はどうなるでしょうか。関数から関数に値を渡すことは、パフォーマンスの観点から意味がありますか? 「pythonic」コードとパフォーマンスの間で最適な妥協点を提供するのはどのパラダイムですか?ab

4

1 に答える 1

6

関数内で識別子を変更する場合にのみ、識別子がグローバルであることを示す必要があります。参照するだけでa代入しない場合は、ステートメントbを省略できます。global

たとえば、関数もグローバルです。recalculateIntermediateParametersは割り当てられておらず、参照されているだけであり、そうするために使用global recalculateIntermediateParametersする必要はありませんでした。

Python は、異なるオペコードを使用して、ローカルとグローバルに割り当てます。もしあなたがそうするなら:

def foo():
    a = 10

def foo():
    global a
    a = 10

Python は、ローカルまたはグローバルとして更新するために2 つの異なる操作を使用します。a

より一般的に言えば、グローバルを使用してstateを渡すことは避けたいと考えています。代わりに、値をパラメーターとして (プリミティブ、または辞書やカスタム クラス インスタンスなどの複合構造を使用して) 渡します。グローバルを個別に追跡する代わりに、関数を介して状態を追跡できるため、コードの読み取りとデバッグが容易になります。

于 2013-07-07T14:43:50.100 に答える