在python中,异常是否可能发生在调用之后,但在调用之后的try块之前?
给定一个函数调用和紧随其后的try块,是否存在调用正常返回但引发异常且try块未捕获的情况 例如: 例1 资源=获取资源 尝试: 做点什么 更多的代码。。。 最后: 资源关闭 acquire_a_资源是否可能正常返回,但不会调用resource.close 或者换句话说,是否存在以下情况: 例2 资源=无 尝试: 资源=获取资源 做点什么 更多的代码。。。 最后: 如果资源: 资源关闭 会比示例1更安全吗在python中,异常是否可能发生在调用之后,但在调用之后的try块之前?,python,multithreading,exception,signals,keyboardinterrupt,Python,Multithreading,Exception,Signals,Keyboardinterrupt,给定一个函数调用和紧随其后的try块,是否存在调用正常返回但引发异常且try块未捕获的情况 例如: 例1 资源=获取资源 尝试: 做点什么 更多的代码。。。 最后: 资源关闭 acquire_a_资源是否可能正常返回,但不会调用resource.close 或者换句话说,是否存在以下情况: 例2 资源=无 尝试: 资源=获取资源 做点什么 更多的代码。。。 最后: 如果资源: 资源关闭 会比示例1更安全吗 可能是因为键盘中断/线程/信号的原因?是的,至少在理论上是这样,但在CPython中不是这
可能是因为键盘中断/线程/信号的原因?是的,至少在理论上是这样,但在CPython中不是这样。详情请参见脚注。线程并不是特别相关,但键盘中断场景正好合适:
resource = acquire_a_resource()
调用函数。函数获取资源并返回句柄,然后在变量赋值过程中,1键盘中断发生。因此:
try:
不运行键盘,相反会发生中断异常,保留当前函数并解除变量绑定
第二个版本通过finally子句,因此假设resource找到它boolean-truth-y,则会调用resource.close
请注意,实际上触发此操作通常非常困难:您必须对中断进行正确计时。您可以通过在尝试之前添加time.sleep1来大幅增加比赛窗口
对于许多情况,with语句都很有效:
with acquire_a_resource() as resource:
resource.do_something()
其中关闭内置于_退出_方法中。即使该块通过异常转义,该方法也会运行
1通常,实现必须完成获取的资源与变量的绑定,否则会出现无法恢复的竞争。在CPython中,之所以会发生这种情况,是因为解释器检查语句之间的中断,有时还会检查源代码中的关键位置
CPython实际上添加了另一个特殊情况:
/*定期做一些事情。每次都是这样做的
循环会增加太多的开销,所以我们会这样做
只有每N条指令。我们也会这样做,如果
``已设置pendingcalls_to_do,即当异步
事件需要注意,例如信号处理程序或
异步I/O处理程序;请参阅Py_AddPendingCall和
Py_在上面打电话*/
如果原子负载松弛&\u PyRuntime.ceval.eval\u断路器{
操作码=_Py_操作码*下一个指令;
如果操作码==SETUP\u||
操作码==安装程序||
操作码==在异步之前||
操作码==从{
/*我们跳过运行信号处理程序和其他
挂起的电话:
-如果我们即将进入“with:”,它将阻止
在通用习惯用法中发出资源警告
'将openpath作为文件:'。
-如果我们要输入'async with:'。
-如果我们即将进入一个try/finally not的“try:”
*非常有用,但在某些情况下可能会有所帮助
传统的
-如果我们要恢复嵌套的“从”或
“等待”呼叫,然后每一帧都停在
作为它的下一个操作码。如果用户点击control-C,我们希望
在到达最里面的帧之前,请等待
运行信号处理程序并引发键盘中断
见bpo-30039。
*/
转到快速下一个操作码;
}
Python/ceval.c,靠近第1000行
实际上,try行确实运行了,因为这里最后有一个设置。我一点也不清楚其他Python实现是否也做同样的事情。是的,至少在理论上是这样,但在CPython中不是这样。请参见脚注了解详细信息。线程并不是特别相关,但键盘中断场景恰好合适:
resource = acquire_a_resource()
调用函数。函数获取资源并返回句柄,然后在变量赋值过程中,1键盘中断发生。因此:
try:
不运行键盘,相反会发生中断异常,保留当前函数并解除变量绑定
第二个版本通过finally子句,因此假设resource找到它boolean-truth-y,则会调用resource.close
请注意,实际触发此操作通常非常困难:您必须对中断进行正确的计时。您可以通过在尝试之前添加time.sleep1来大幅增加竞赛窗口
对于许多情况,with语句都很有效:
with acquire_a_resource() as resource:
resource.do_something()
其中关闭内置于_退出_方法中。即使通过异常转义块,该方法也会运行<
/p>
1通常,实现必须完成获取的资源与变量的绑定,否则会出现无法恢复的竞争。在CPython中,之所以会发生这种情况,是因为解释器检查语句之间的中断,有时还会检查源代码中的关键位置
CPython实际上添加了另一个特殊情况:
/*定期做一些事情。每次都是这样做的
循环会增加太多的开销,所以我们会这样做
只有每N条指令。我们也会这样做,如果
``已设置pendingcalls_to_do,即当异步
事件需要注意,例如信号处理程序或
异步I/O处理程序;请参阅Py_AddPendingCall和
Py_在上面打电话*/
如果原子负载松弛&\u PyRuntime.ceval.eval\u断路器{
操作码=_Py_操作码*下一个指令;
如果操作码==SETUP\u||
操作码==安装程序||
操作码==在异步之前||
操作码==从{
/*我们跳过运行信号处理程序和其他
挂起的电话:
-如果我们即将进入“with:”,它将阻止
在通用习惯用法中发出资源警告
'将openpath作为文件:'。
-如果我们要输入'async with:'。
-如果我们即将进入一个try/finally not的“try:”
*非常有用,但在某些情况下可能会有所帮助
传统的
-如果我们要恢复嵌套的“从”或
“等待”呼叫,然后每一帧都停在
作为它的下一个操作码。如果用户点击control-C,我们希望
在到达最里面的帧之前,请等待
运行信号处理程序并引发键盘中断
见bpo-30039。
*/
转到快速下一个操作码;
}
Python/ceval.c,靠近第1000行
实际上,try行确实在运行,因为这里终于有了一个安装程序。我根本不清楚其他Python实现是否也做了同样的事情。我很确定with也有同样的中断问题。with捕获了类对象中的资源,当u enter uuu返回时,资源将绑定到该类对象中__exit__使用类对象的资源副本来完成关闭。这确实意味着资源管理器本身必须仔细编码:构造没有资源绑定的类,然后在一个操作中获取和绑定。实现有一定程度的友好性:您必须假设var=acquire本身是原子的,即。,信号发生,引发异常发生在绑定之前或之后,不是在绑定期间,而是在绑定期间。即使使用with,键盘中断也可以在获取资源成功和设置with块之间到达,这忽略了未询问但更危险的可能性,即在获取期间到达键盘中断re_a__________________________________________________________________________d通常有一个函数来延迟键盘中断和信号,这样您就可以编写:with defer…:代码,其中…mask/set/list/whates中的任何信号都会一直保持到块退出为止。我很确定with也有相同的中断问题。with捕获类对象中的资源,当\uuuuu enter\uuuuuuu返回。\uuuuuu exit\uuuuuuuu使用类对象的资源副本来完成关闭。这意味着资源管理器本身必须仔细编码:在没有资源绑定的情况下构造类,然后在一个操作中获取和绑定。实现有一定程度的便利性:必须假设var=acquire本身是原子的,即,信号发生,引发异常发生在绑定之前或之后,不是在绑定期间,而是如此。即使使用with,键盘中断也可能出现在acquire_a_资源成功与with块设置之间,这忽略了未询问但更危险的键盘中断可能性pt在acquire_________________________________________________________________________想一想Python应该有一个函数来延迟键盘中断和信号,这样您就可以编写:with defer…:代码,其中…mask/set/list/whatever中的任何信号都会一直保持到block ex 它的