3

次のような関数を使用して、Python で奇妙なことに遭遇しました。

    def foo(x):
        if int(x)!=4:
            x = raw_input("Wrong guess, please enter new value: " )
            foo(x)
        else:
            print "Good Job! %s was right"%x
        return x

    value = foo(x=raw_input("Guess a Number between 1 and 10: "))
    print value

たとえば、「1」、「2」、「3」、「4」と入力すると、次のように出力されます。

Good Job! 4 was right
2

関数が正しい答えを正しく識別しているように見えるため、これは紛らわしいですが、そうすると、最新の応答ではなく、2 番目の応答である値が返されます。

この再帰関数の「x」のバインディングで何が起こっているのか、誰か説明できますか?

4

3 に答える 3

4

どれどれ!

value = foo(raw_input())
# foo is the same as in the question, I won't repeat it here
print value

foo の中では、次のようになります。

# foo(1) calls foo(2) and sets x to 2
# foo(2) calls foo(3) and sets x to 3
# foo(3) calls foo(4) and sets x to 4
# foo(4) does:
print "Good Job! 4 was right"
return 4 # to foo(3)
# foo(3) does:
return 4 # to foo(2)
# foo(2) does:
return 3 # to foo(1)
# foo(1) does:
return 2 # to main

(最も外側の再帰からの) main への戻り値はであるため2、それがvalue残ります。

これを修正するには、繰り返しにすることができます。

def iter_foo(x):
    while int(x) != 4:
        x = raw_input("Wrong guess. Try again! ")
    print "Good Job! %s was right" % x
    return x

または、各再帰が新しい関数の結果を返すようにします

def recurse_foo(x):
    if int(x) != 4:
        return foo(raw_input("Wrong guess. Try again! "))
    else:
        print "Good Job! %s was right!" % x
        return x
于 2014-08-25T17:55:13.360 に答える
3

だから、それは主にあなたが欠けているからreturnです

def foo(x):
    if int(x)!=4:
        x = raw_input("Wrong guess, please enter new value: " )
        foo(x) # <-- need return
    else:
        print "Good Job! %s was right"%x
    return x

value = foo(x=raw_input("Guess a Number between 1 and 10: "))
print value

何が起こっているかというとfoo(1)、4 と等しくない を呼び出し、x2 に割り当てます。これが最後xに割り当てられる値です。

  • 再帰foo(x)は値を返しますが、何にも割り当てられていないか、再帰呼び出しから返されていません。
  • 最後xに受け取った値は 2 だったので、初期値はそれをfoo(1)返します

だからどちらか

x = foo(x)

または

return foo(x)

ハイライトした行で

于 2014-08-25T17:54:47.383 に答える
2

次のコードを試してください。

def foo(x):
    if int(x)!=4:
        x = raw_input("Wrong guess, please enter new value: " )
        return foo(x)
    else:
        print "Good Job! %s was right"%x
        return x

value = foo(x=raw_input("Guess a Number between 1 and 10: "))
print value

関数 foo を呼び出すたびに、新しい変数 x が作成されると考えることができます。したがって、再帰呼び出しは一連の変数 x1、x2、x3 などを作成します。したがって、関数呼び出しが戻ると、ローカル変数 x は変更されません。そのため、最後の再帰呼び出し (4) からの代入ではなく 2 を取得します。関数に渡される変数を変更する場合は、値ではなく参照 (またはオブジェクト) で渡す必要があります。[詳細については、この記事を参照してください: http://uvesway.wordpress.com/2013/02/18/passing-arguments-to-a-function-by-value-by-reference-by-object/]

于 2014-08-25T18:04:26.490 に答える