3

これが私のコードです:

def f(x):
    def g(n):
        if n < 10:
            x = x + 1
            g(n + 1)
    g(0)

f(0)を評価すると、「割り当て前にxが参照されました」というエラーが発生します。

ただし、「x = x + 1」の代わりに「printx」を使用すると、機能します。

gの範囲では、xは「使用オカレンス」としてのみ使用でき、「バインディングオカレンス」としては使用できないようです。問題は、fがxの値だけをgに渡すことだと思います。

私はそれを正しく理解していますか?そうでない場合、「x = x + 1」の左側が参照前に定義されていない理由を誰かが説明できますか?

ありがとう

4

2 に答える 2

5

あなたはそれを正しく理解しています。xPython2ではネストされたスコープでにを割り当てるために使用することはできません。

nonlocalPython 3でも、変数を;としてマークすることで、バインディングオカレンスとして使用できます。これは、このユースケースのために導入されたキーワードです。

def f(x):
    def g(n):
        nonlocal x
        if n < 10:
            x = x + 1
            g(n + 1)
    g(0)

Python 2では、いくつかの回避策があります。ミュータブルを使用してバインドする必要がないようにするか、(ab)関数プロパティを使用します。

def f(x):
    x = [x]   # lists are mutable
    def g(n):
        if n < 10:
            x[0] = x[0] + 1   # not assigning, but mutating (x.__setitem__(0, newvalue))
            g(n + 1)
    g(0)

また

def f(x):
    def g(n):
        if n < 10:
            g.x = g.x + 1
            g(n + 1)
    g.x = x  # attribute on the function!
    g(0)
于 2013-02-03T23:08:42.333 に答える
1

はい、名前への割り当ては、値の読み取りとは異なります。関数で割り当てられた名前は、特に指定しない限り、その関数のローカル変数と見なされます。

Python 2では、「他の方法で指定」する唯一の方法は、globalステートメントを使用してグローバル変数に割り当てることです。Python 3にnonlocalは、より高い(ただし必ずしもグローバルではない)スコープの変数に値を割り当てるステートメントもあります。

あなたの例でxは、はより高いが非グローバルスコープ(関数f)にあります。したがって、Python 2x内からに割り当てる方法はありません。Python3では、のステートメントを使用して割り当てることができます。gnonlocal xg

于 2013-02-03T23:09:14.617 に答える