【发布时间】:2020-05-26 07:28:07
【问题描述】:
我在一个模块中有一个函数,它执行如下操作:
def some_func():
try:
# do some error-prone thing
raise ValueError
return 'calculated foo'
except AttributeError as err:
# handle it
pass
except:
print('Some other error happened, let\'s reraise it....')
raise
else:
pass
finally:
return 'default foo'
然后在我的主程序中,
try:
val = some_func()
print('val=', val)
except:
print('In main except')
raise
else:
print('In main else')
pass
finally:
print('And we\'re done')
我的输出是:
发生了一些其他错误,让我们重新提出它....
val= 默认 foo
主要是其他
我们完成了
不会引发异常。
冒着遗漏一些显而易见的东西的风险,为什么ValueError 不在我的主目录中被重新加注?似乎some_func() 中的finally 中的return 导致异常不会被重新引发,但这对我来说似乎很奇怪,我找不到它的任何文档。这是我认为应该发生的事情,想了解我在哪里。
- 我在主程序中调用
some_func() -
some_func()引发 ValueError - ValueError 在
some_func()except中被捕获,打印“发生其他错误”并重新引发它。 - 回到 main,我认为重新引发的 ValueError 应该被
except捕获,应该打印 'In main except',重新引发,然后异常本身应该未被捕获,导致程序停。但我没有提出任何例外,而是在else子句中结束。
【问题讨论】:
-
如果您希望异常堆栈在执行 finally 块后被解开......为什么它会返回一个值?
-
这是一个例子,但我的理解是它应该没有区别。从文档中,“如果在 try 子句执行期间发生异常,则异常可以由 except 子句处理。如果异常未由 except 子句处理,则在 finally 子句执行后重新引发异常。”那么我的
finally返回一个与重新提出例外无关的值不是事实吗? -
没有。对于您正在尝试做的事情,返回应该在“else”块中,而不是“finally”块中。 Python 将不得不重新引发异常before 返回,因为在返回后异常将不再存在以重新引发。python 可以处理此代码实际上只有两种合理的方式:(1)执行返回,中止任何正在进行的异常堆栈展开,这就是它所做的,或者(2)作为语法错误
-
实际上,现在我想起来了,如果你给它这个代码,pylint 会在该行给你一个警告
标签: python exception error-handling try-catch