Python:递归函数中的变量绑定

时间:2014-08-25 17:48:07

标签: python function recursion python-bindings

我使用类似以下的函数在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

这很令人困惑,因为似乎该功能正在成功识别正确的答案,但在这样做之后,它返回的值是给定的第二个响应,而不是最近的响应。

有人能解释一下这个递归函数中“x”的绑定是怎么回事吗?

3 个答案:

答案 0 :(得分: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

或者使EACH递归返回新函数的结果

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

答案 1 :(得分:3)

所以这主要是因为你错过了<{p>中的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,将x分配给2,这是x分配给的最后一个值,所以

  • 您的递归foo(x)会返回一个值,但不会将其分配给任何内容或从递归调用返回。
  • 收到的最后一个值x为2,这就是初始foo(1)返回的内容

所以要么

x = foo(x)

或者

return foo(x)

在我突出显示的行

答案 2 :(得分: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不变。这就是为什么你仍然得到2而不是最后一次递归调用的赋值(4)。如果要更改传递给函数的变量,则需要通过引用(或对象)而不是值传递它。 [有关详细信息,请参阅此文章:http://uvesway.wordpress.com/2013/02/18/passing-arguments-to-a-function-by-value-by-reference-by-object/]