版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011510825/article/details/86360478
昨天发现try-except-finally中使用递归,结果掉进坑里了,爬了好久,好久.....
需求是这样的,我们请求三方一个接口,这个接口呢,有时候不稳定,需要重试,最大重试测试是5次,当时的代码大致是这样的。
def request_interfaces(num):
print("request_interfaces num:%s" % num)
raise Exception("request_interfaces error")
def exce_function(max_retry=5):
num = 0
try:
request_interfaces(num)
except:
num += 1
print("except num:%s" % num)
if num < max_retry:
request_interfaces(num)
finally:
print("finally num:%s" % num)
print("end!!!")
我的想法,肯定是他可以循环重试5次,然后退出。。可事实却是他只能循环两次,就是他进入一次except,然后再次try碰到raise的时候,直接执行了finally。
输出如下:
>>> exce_function()
request_interfaces num:0
except num:1
request_interfaces num:1
finally num:1
Traceback (most recent call last):
File "<stdin>", line 4, in exce_function
File "<stdin>", line 3, in request_interfaces
Exception: request_interfaces error
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 9, in exce_function
File "<stdin>", line 3, in request_interfaces
Exception: request_interfaces error
上面的递归如果觉得复杂,我们用下面这种好理解的
def exec_function():
num = 0
try:
request_interfaces(0)
except:
request_interfaces(1)
request_interfaces(2)
request_interfaces(3)
finally:
print("finally num:%s" % num)
print("end!!!")
结果是一样的
>>> exec_function()
request_interfaces num:0
request_interfaces num:1
finally num:0
Traceback (most recent call last):
File "<stdin>", line 4, in exec_function
File "<stdin>", line 3, in request_interfaces
Exception: request_interfaces error
这里的问题, request_interfaces没有进行异常捕捉,exec_function的try-except-finally跟request_interfaces完全没有关系,可以理解为直接执行了request_interfaces函数(我们容易被exce_function的try-except误导,以为也是进入try-except了)。
这里改动的办法有很多,我的选择如下:
def request_interfaces(num, max_retry=5):
try:
print("request_interfaces num:%s" % num)
raise Exception("request_interfaces error")
except:
num += 1
print("except num:%s" % num)
if num < max_retry:
request_interfaces(num, max_retry)
finally:
print("finally num:%s" % num)
def exec_function():
num = 0
request_interfaces(num)
print("end!!!")
结果如下(符合预期):
>>> exec_function()
request_interfaces num:0
except num:1
request_interfaces num:1
except num:2
request_interfaces num:2
except num:3
request_interfaces num:3
except num:4
request_interfaces num:4
except num:5
finally num:5
finally num:4
finally num:3
finally num:2
finally num:1
end!!!