Python 中 `finally` 的执行时机与 `return` 的微妙关系

文章目录

    • Python 中 `finally` 的执行时机与 `return` 的微妙关系
      • 一、`finally` 的执行时机
        • 示例
      • 二、`return` 与 `finally` 的交互:可变对象的陷阱
        • 示例 :可变对象在 `finally` 中被修改
        • 示例 :不可变对象的安全隔离
      • 三、`finally` 中的 `return`:危险的覆盖行为
        • 示例 4:`finally` 覆盖返回值
        • 示例 5:`finally` 吞没异常
      • 四、总结与最佳实践

Python 中 finally 的执行时机与 return 的微妙关系

一、finally 的执行时机

在 Python 中,finally 代码块的执行遵循一个核心原则:无论 tryexcept 中是否发生异常、是否遇到 returnbreakfinally 总会执行。这一机制使得 finally 成为资源清理(如关闭文件、释放锁)的黄金位置。

示例
def basic_finally():try:print("执行 try 块")return "try 返回值"except:passfinally:print("执行 finally 块")print(basic_finally())

输出:

执行 try 块
执行 finally 块
try 返回值

关键结论

  • finallyreturn 之后声明,但在 return 之前执行
  • 函数返回值在 finally 执行前被暂存,但 finally 中的操作仍可能影响返回值(见下文)。

二、returnfinally 的交互:可变对象的陷阱

return 遇到可变对象(如列表、字典)时,finally 中的代码可能“悄无声息”地修改返回值。这是因为 Python 返回的是对象的引用,而非副本。

示例 :可变对象在 finally 中被修改
def mutable_return():x = [1, 2, 3]try:x.append(4)return x  # 暂存返回值 [1,2,3,4]finally:x.append(5)  # 修改原列表print("finally 中修改后的 x:", x)result = mutable_return()
print("最终返回值:", result)

输出:

finally 中修改后的 x: [1, 2, 3, 4, 5]
最终返回值: [1, 2, 3, 4, 5]

函数中的return语句会将当前的值暂存,然后执行finally块,如果在finally中修改了返回值引用的对象,对于可变对象来说,这些修改会反映到返回值中,因为返回的是对象的引用,而不是副本

关键结论

  • return x 暂存的是列表 x 的引用,而非数据副本。
  • finally 中对 x 的修改会直接影响返回值,因为它们指向同一内存地址。

示例 :不可变对象的安全隔离
def immutable_return():x = 100try:x += 10return x  # 暂存返回值 110finally:x += 20  # 创建新对象,不影响原返回值print("finally 中的 x:", x)result = immutable_return()
print("最终返回值:", result)

输出:

finally 中的 x: 130
最终返回值: 110

关键结论

  • 不可变对象(如整数、字符串)的修改会创建新对象,原始返回值不受影响。
  • finally 中的操作仅影响函数内的局部变量,与已暂存的返回值无关。

三、finally 中的 return:危险的覆盖行为

finally 中也有 return,它会直接覆盖之前的返回值,并可能导致异常被静默忽略。

示例 4:finally 覆盖返回值
def dangerous_finally():try:return "来自 try 的返回值"finally:return "来自 finally 的返回值"  # 覆盖 try 的返回值print(dangerous_finally())

输出:

来自 finally 的返回值
示例 5:finally 吞没异常
def hide_exception():try:raise ValueError("严重错误!")except:return "来自 except 的返回值"finally:return "来自 finally 的返回值"  # 覆盖异常处理结果print(hide_exception())

输出:

来自 finally 的返回值

关键结论

  • 避免在 finally 中使用 return:除非明确需要覆盖返回值或忽略异常。
  • 覆盖行为会隐藏潜在错误,导致调试困难。

四、总结与最佳实践

  1. 执行顺序
    try/except → 暂存返回值 → 执行 finally → 返回暂存值

  2. 返回值规则

    • 对可变对象:finally 中的修改直接影响返回值(返回的是引用)。
    • 对不可变对象:finally 中的修改不影响返回值(返回的是副本)。
  3. 避坑指南

    • 禁止finally 中使用 return,除非有明确需求。
    • 若需返回可变对象,优先返回其副本(如 return x.copy())。
    • finally 中仅处理资源释放,避免业务逻辑。

若有错误与不足请指出,关注DPT一起进步吧!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/69955.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

问题的价值 ( Value of Question ) 公式

一、什么是问题的价值 我们的人生、工作的期间、瞬息万变的商业环境中,我们必然会面对很多问题,也会提出很多问题。 但这些问题是否具有回答的 价值,应该如何 衡量 呢? 简单如,女朋友问今晚应该吃什么、世界如何才能…

一文了解阿里的 Qwen2.5 模型

最近被DeepSeek刷屏了,但是在之外阿里在2025年1月28日推出了Qwen 2.5 Max模型。 Qwen2.5-Max 的特点:大规模的 MoE 模型,预训练于超 20 万亿 tokens,并经过 SFT 和 RLHF 后训练。 性能表现:在多个基准测试中与领先模型…

悬浮按钮和可交互提示的使用

xmlns:app“http://schemas.android.com/apk/res-auto” xmlns:tools“http://schemas.android.com/tools” android:id“id/drawerLayout” android:layout_width“match_parent” android:layout_height“match_parent” tools:context“.MainActivity”> <andro…

基于Django的Boss直聘IT岗位可视化分析系统的设计与实现

【Django】基于Django的Boss直聘IT岗位可视化分析系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 该系统采用Python作为主要开发语言&#xff0c;利用Django这一高效、安全的W…

Hive:复杂数据类型之Map函数

Map函数 是Hive里面的一种复杂数据类型, 用于存储键值对集合。Map中的键和值可以是基础类型或复合类型&#xff0c;这使得Map在处理需要关联存储信息的数据时非常有用。 定义map时,需声明2个属性: key 和 value , map中是 key value 组成一个元素 key-value, key必须为原始类…

C# 继承与多态详解

.NET学习资料 .NET学习资料 .NET学习资料 在 C# 面向对象编程中&#xff0c;继承与多态是两个极为关键的特性&#xff0c;它们赋予了程序强大的复用性和灵活性。理解并掌握这两个特性&#xff0c;是成为一名优秀 C# 开发者的必经之路。 一、C# 继承 1.1 继承的定义与概念 …

为AI聊天工具添加一个知识系统 之77 详细设计之18 正则表达式 之5

本文要点 昨天讨论了 本项目&#xff08;AI聊天工具添加一个知识系统&#xff09;中正则表达式模板的设计中可能要考虑到的一些问题&#xff08;讨论到的内容比较随意&#xff0c;暂时无法确定 那些考虑 是否 应该是正则表达式模板设计要考虑的以及 是否完整&#xff09;。今天…

计算机毕业设计Python动漫推荐系统 漫画推荐系统 动漫视频推荐系统 机器学习 bilibili动漫爬虫 数据可视化 数据分析 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

2025年02月02日Github流行趋势

项目名称&#xff1a;oumi 项目地址url&#xff1a;https://github.com/oumi-ai/oumi 项目语言&#xff1a;Python 历史star数&#xff1a;1416 今日star数&#xff1a;205 项目维护者&#xff1a;xrdaukar, oelachqar, taenin, wizeng23, kaisopos 项目简介&#xff1a;构建最…

谭浩强C语言程序设计(3) 7章

1、递归实现N的阶乘 c复制 #include <cstdio> // 包含标准输入输出库// 计算n的阶乘 int total 0; // 定义全局变量total用于存储阶乘结果// 递归函数计算阶乘 int fac(int a){// 如果输入的数小于0&#xff0c;输出错误信息if (a < 0){printf("%d < 0,err…

python算法和数据结构刷题[2]:链表、队列、栈

链表 链表的节点定义&#xff1a; class Node():def __init__(self,item,nextNone):self.itemitemself.nextNone 删除节点&#xff1a; 删除节点前的节点的next指针指向删除节点的后一个节点 添加节点&#xff1a; 单链表 class Node():"""单链表的结点&quo…

网络工程师 (13)时间管理

一、定义与重要性 项目时间管理是指为确保项目按时完成而采取的一系列规划、安排和控制活动。它始于项目启动阶段&#xff0c;贯穿整个项目生命周期&#xff0c;直至项目结束。时间管理对于项目的成功至关重要&#xff0c;它有助于项目团队明确工作目标和时间节点&#xff0c;增…

2025.2.1——四、php_rce RCE漏洞|PHP框架

题目来源&#xff1a;攻防世界 php_rce 目录 一、打开靶机&#xff0c;整理信息 二、解题思路 step 1&#xff1a;PHP框架漏洞以及RCE漏洞信息 1.PHP常用框架 2.RCE远程命令执行 step 2&#xff1a;根据靶机提示&#xff0c;寻找版本漏洞 step 3&#xff1a;进行攻击…

002 mapper代理开发方式-xml方式

文章目录 代理xml方式UserMapper.javaUser.javadb.propertiesSqlMapConfig.xmlUserMapper.xmlUserMapperTest.javapom.xml 代理 此处使用的是JDK的动态代理方式&#xff0c;延迟加载使用的cglib动态代理方式 代理分为静态代理和动态代理。此处先不说静态代理&#xff0c;因为…

记录 | 基于MaxKB的文字生成视频

目录 前言一、安装SDK二、创建视频函数库三、调试更新时间 前言 参考文章&#xff1a;如何利用智谱全模态免费模型&#xff0c;生成大家都喜欢的图、文、视并茂的文章&#xff01; 自己的感想 本文记录了创建文字生成视频的函数库的过程。如果想复现本文&#xff0c;需要你逐一…

HTML5 技术深度解读:本地存储与地理定位的最佳实践

系列文章目录 01-从零开始学 HTML&#xff1a;构建网页的基本框架与技巧 02-HTML常见文本标签解析&#xff1a;从基础到进阶的全面指南 03-HTML从入门到精通&#xff1a;链接与图像标签全解析 04-HTML 列表标签全解析&#xff1a;无序与有序列表的深度应用 05-HTML表格标签全面…

Error: Expected a mutable image

你的函数用了不支持的图片格式比如我的人脸检测&#xff0c;本来要RGB565我却用JPEG所以报错

算法8--归并

目录 原理经典例题[912. 排序数组](https://leetcode.cn/problems/sort-an-array/description/)[LCR 170. 交易逆序对的总数](https://leetcode.cn/problems/shu-zu-zhong-de-ni-xu-dui-lcof/description/)计算右侧小于当前元素的个数[493. 翻转对](https://leetcode.cn/proble…

RK3568使用opencv(使用摄像头捕获图像数据显示)

文章目录 一、opencv相关的类1. **cv::VideoCapture**2. **cv::Mat**3. **cv::cvtColor**4. **QImage**5. **QPixmap**总结二、代码实现一、opencv相关的类 1. cv::VideoCapture cv::VideoCapture 是 OpenCV 中用于视频捕捉的类,常用于从摄像头、视频文件、或者图像序列中捕…

深度学习查漏补缺:1.梯度消失、梯度爆炸和残差块

一、梯度消失 梯度消失的根本原因在于 激活函数的性质和链式法则的计算&#xff1a; 激活函数的导数很小&#xff1a; 常见的激活函数&#xff08;例如 Sigmoid 和 Tanh&#xff09;在输入较大或较小时&#xff0c;输出趋于饱和&#xff08;Sigmoid 的输出趋于 0 或 1&#xf…