def foo():
try:
html = get(url)
while (html is nogood):
foo()
return html
except Exception as e:
changeip()
foo()
函数foo
只是在文本中返回一个好的html
但是,该函数有时会返回None
并导致其生成
当Exception
被抓住时。
所以我将最后一行更改为return foo()
,它按预期工作。
问题是为什么?在catch上,它只是再次调用foo,最终会在文本中返回一个好的html,为什么我必须添加额外的return
?
由于
答案 0 :(得分:2)
根本不需要递归解决方案。在changeip
中,只需保持循环,直到你有一个好的HTML。在每次循环之后,做一些事情来提高获得一个好的html的机会(def foo():
while True:
try:
html = get(url)
if is_good(html):
return html
except Exception: # Need specific exception, do not catch all
changeip()
是否可以用于此目的?)。
sapply
答案 1 :(得分:1)
如果失败,请考虑第一个foo()
返回的内容。
从foo1
致电main
,但失败了 - > foo1
调用foo2
并成功 - > foo2
将html返回foo1
- >在foo1
中没有其他代码可以执行,因此它会返回None
。
当foo
最终成功时,它不会将html
返回给main
,它会将其返回给最后一个调用者,在本例中为foo1
。
问题在于,在第一个呼叫失败后,您将丢弃任何foo
呼叫的结果。如上所述,您需要将最后一行的html返回到return foo()
。
答案 2 :(得分:1)
想象一下房间中间的一个大纸板箱。此框代表您的功能foo
。现在想象一下,return
代替change_this_boxes_colour
意味着它的作用,我们的意思是def bar():
return BLUE # every `bar` box turns `BLUE`
def foo():
bar()
print(foo()) # prints None
。无论盒子变成什么颜色(返回值,真的)都可以从您目前所在的房间看到。这就是函数为您提供信息的方式。
现在,在这个大纸板盒里面有点神奇,因为盒子可以创建自己的小盒子(包括自己的副本!)。那么让我们看看一些代码,然后用盒子术语来思考:
bar
简单的代码对吗?这是代码的超级蒸馏版本。我们在另一个函数中调用一个函数,但没有得到它的返回值(颜色)。
再次考虑盒子,我们在房间中间放置了一个大的(无色)盒子。但它自己的盒子里面(BLUE
)。正如预期的那样,此框会变为foo
。但是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
在您的情况下,$absLink
碰巧在自己的框中创建自己的版本,但原则仍然适用。