简体   繁体   English

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

[英]Python: variable bindings in recursive functions

I came across some weirdness in Python using a function similar to the following: 我使用类似于以下的函数在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

If I enter, for instance: "1" then "2" then "3" then "4", I get the following printed out: 如果我输入,例如:“1”然后“2”然后“3”然后“4”,我打印出以下内容:

Good Job! 4 was right
2

This is confusing, since it seems the function is successfully identifying the right answer, but after doing so it is returning a value that was the 2nd response given, instead of the most recent response. 这很令人困惑,因为看起来该函数似乎成功识别了正确的答案,但在这样做之后,它返回的值是给定的第二个响应,而不是最近的响应。

Can anyone explain what's going on with the binding of "x" in this recursive function? 任何人都可以解释这个递归函数中绑定“x”的情况吗?

Let's see! 让我们来看看!

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

Inside your foo, you get this: 在你的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

Since the return value to main (from the outermost recursion) is 2 , that's what value remains. 由于main(从最外面的递归)的返回值是2 ,这就是剩下的value

To fix this, you can either make it iterative: 要解决这个问题,你可以让它迭代:

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

Or make EACH recursion return the result of the new function 或者使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

So it's mostly because you are missing a return in 所以这主要是因为你错过了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

What's happening is it calls foo(1) , which is not equal to 4, assigns x to 2, and that is the last value that x gets assigned to, so 发生的事情是调用foo(1) ,它不等于4,将x赋值为2,这是x被赋值的最后一个值,所以

  • Your recursive foo(x) returns a value, but it isn't assigned to anything or returned from the recursive call. 递归foo(x)返回一个值,但它没有分配给任何东西或从递归调用返回。
  • The last value x received was 2, so that is what the initial foo(1) returns 的最后一个值x接收为2,所以这就是初始foo(1)返回

So either 所以要么

x = foo(x)

Or 要么

return foo(x)

On the line I highlighted 在线上我突出显示

Try the following code: 请尝试以下代码:

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

You can think each call to the function foo, creates a new variable x. 你可以认为每次调用函数foo,都会创建一个新的变量x。 Thus, the recursive calls make a sequence of variables x1, x2, x3, etc. Thus when a function call returns, your local variable x is unchanged. 因此,递归调用产生一系列变量x1,x2,x3等。因此,当函数调用返回时,您的局部变量x不变。 That's why you still get 2 instead of the assignment from the last recursive call (4). 这就是为什么你仍然得到2而不是最后一次递归调用的赋值(4)。 If you want to change the variable passed into a function, you need to pass it by reference (or object), rather than by value. 如果要更改传递给函数的变量,则需要通过引用(或对象)而不是值传递它。 [See this article for more details: http://uvesway.wordpress.com/2013/02/18/passing-arguments-to-a-function-by-value-by-reference-by-object/] [有关详细信息,请参阅此文章: http//uvesway.wordpress.com/2013/02/18/passing-arguments-to-a-function-by-value-by-reference-by-object/]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM