尝试直到没有异常?

Try until no exception?

def foo():
    try:
        html = get(url)
        while (html is nogood):
            foo()
        return html
    except Exception as e:
        changeip()
        foo()

函数 foo 只是 return 在文本中是一个很好的 html。
但是,该函数有时 returns None 并且它导致
Exception 被捕获时。

所以我将最后一行更改为 return foo() 并且它按预期工作。

问题是为什么?在捕获时,它只是再次调用 foo,这最终会 return 一个很好的文本 html,为什么我必须放置额外的 return

谢谢

想想第一个foo()return如果失败了

main 调用 foo1 失败 -> foo1 调用 foo2 并成功 -> foo2 returns html 到 foo1 -> foo1 中没有其他代码要执行,所以它 returns None.

foo最终成功时,它不会returnhtmlmain,而是return传给最后一个调用者,在这个案例是 foo1.

问题是您在第一个调用失败后丢弃任何 foo 调用的结果。您需要 return html 在链的最后一行返回到您提到的 return foo()

您根本不需要递归解决方案。在foo中,一直循环直到你有一个好的html。每次循环后,做一些事情来提高获得好的 html 的机会(changeip 是否为此目的起作用?)。

def foo():
    while True:
        try:
            html = get(url)
            if is_good(html):
                return html
        except Exception:  # Need specific exception, do not catch all
            changeip()

想象一下房间中央有一个大纸板箱。此框代表您的函数,foo。现在想象一下,我们让它的意思不是 return 的意思,而是类似于 change_this_boxes_colour 的意思。无论方框变成什么颜色(实际上是 return 值),都可以从您当前所在的房间看到。这就是函数为您提供信息的方式。

现在,这个大纸箱里面有点神奇,因为盒子可以创建自己的小盒子(包括自己的副本!)。那么让我们看一些代码,然后用盒子的术语来思考它:

def bar():
    return BLUE  # every `bar` box turns `BLUE`

def foo():
    bar()

print(foo())  # prints None

简单的代码吧?这是您的代码的超级提炼版本。我们在另一个函数中调用一个函数,但没有得到它的 return 值(颜色)。

再次考虑盒子,我们在房间中间有一个大(无色)盒子。但它在自己内部制作了自己的盒子(bar)。正如预期的那样,此框变为 BLUE。但是 foo 没有设置颜色(return 值),所以它保持无色。

虽然我们仍然站在大 foo 框外面,所以我们看不到 bar 框是什么颜色。如果我们想知道 bar 变成了什么颜色,foo 必须告诉我们。这可以通过要求 foo 将自己设置为与 bar 相同的颜色来实现。在这种情况下,"BLUE".

def bar():
    return "BLUE"  # every `bar` box turns "BLUE"

def foo():
    return bar()  # change our colour to the same colour as `bar`

print(foo())  # prints "BLUE"

在你的例子中,foo 恰好在它自己的盒子里创建了它自己的版本,但原则仍然适用。