当前位置: 首页 > news >正文

Python 之进阶语法:with...as...

1. Python with…as…是什么

Python 的 with…as… 语句,就像一个贴心的管家,负责照顾你的资源,让你不再担心忘记关闭文件、网络连接或数据库事务等。这个管家在你进入“房间”时自动打开门,离开时帮你把门关上,真的是非常贴心!

这个管家的工作方式很简单,你只需要在 with 后面跟上你要管理的资源,然后在 as 后面给这个资源起个名字。一旦你进入了这个“房间”,这个资源就被自动管理了。

1.1 with…as…语法结构
with expression [as target]:with body

参数说明:

expression:是一个需要执行的表达式;
target:是一个变量或者元组,存储的是expression表达式执行返回的结果,[ ]表示该参数为可选参数。

1.2 with…as…用法示例

例如,当你打开一个文件时,你可能会这样写:

file = open("example.txt", "r")  # 手动打开
content = file.read()  
file.close()  # 手动关闭

但是这样写有个问题,如果代码在读取文件内容或关闭文件时出现异常,文件可能不会被正确关闭。这时,你就可以请出 with…as… 语句来帮忙:

with open("example.txt", "r") as file:  content = file.read()  # 在这里你可以放心地使用file,不必担心忘记关闭它。

 这样,无论在 with 块中的代码是否出现异常,文件都会在退出块时被自动关闭,你就不必再担心忘记关闭文件了。

with…as…语句,在Python中叫做:上下文管理器,它在 Python 中实现了自动分配并释放资源。

2. Python with…as…工作原理
2.1 with…as…的由来

with…as 是 python 的控制流语句,像 if ,while一样。

with…as 语句是简化版的 try…except…finally语句。

先理解一下 try…except…finally 语句是干啥的。

实际上 try…except 语句和 try…finally 语句是两种语句,用于不同的场景。但是当二者结合在一起时,可以“实现稳定性和灵活性更好的设计”。

2.1.1 try…except 语句

用于处理程序执行过程中的异常情况,比如语法错误、从未定义变量上取值等等,也就是一些python程序本身引发的异常、报错。比如你在python下面输入 1 / 0:

a = 1 / 0
print(a)
# ZeroDivisionError: division by zero

是的,上面的代码会引发一个ZeroDivisionError异常,因为它在尝试将1除以0。在Python中,任何数字除以0都是未定义的,所以会引发这个错误。

如果你想避免这个错误,你可以使用tryexcept语句来捕获这个异常:

# 声明变量a,并赋值为1除以0,这会导致ZeroDivisionError  
a = 1 / 0  # 尝试执行接下来的代码块,如果发生异常,则执行except块  
try:  # 打印变量a的值,因为a = 1 / 0,所以这里会引发ZeroDivisionError  print(a)  # 如果try块中的代码引发ZeroDivisionError异常,则执行此except块  
except ZeroDivisionError:    # 当除以零时,打印一个错误消息  print("Division by zero is not allowed!")

这样,当尝试除以零时,程序不会崩溃,而是会输出一个错误消息。

try…except 的标准格式

try:# normal block
except A:# exc A block
except:# exc other block
else:# noError block 

程序执行流程是:

–>执行normal block

–>发现有A错误,执行 exc A block(即处理异常)

–>结束

如果没有A错误呢?

–>执行normal block

–>发现B错误,开始寻找匹配B的异常处理方法,发现A,跳过,发现except others(即except:),执行exc other block

–>结束

如果没有错误呢?

–>执行normal block

–>全程没有错误,跳入else 执行noError block

–>结束

我们发现,一旦跳入了某条except语句,就会执行相应的异常处理方法(block),执行完毕就会结束。不会再返回try的normal block继续执行了。

try:a = 1 / 2  # a normal number/variableprint(a)b = 1 / 0  # an abnormal number/variableprint(b)c = 2 / 1  # a normal number/variableprint(c)
except:print("Error")

结果是,先打出了一个0.5,又打出了一个Error。就是把ZeroDivisionError错误捕获了。

先执行 try 后面这一堆语句,由上至下:

  • step1: a 正常,打印a. 于是打印出0.5 (python3.x以后都输出浮点数)
  • step2: b, 不正常了,0 不能做除数,所以这是一个错误。直接跳到except报错去。于是打印了Error。
  • step3: 其实没有step3,因为程序结束了。c是在错误发生之后的b语句后才出现,根本轮不到执行它。也就看不到打印出的c了

但这还不是 try…except 的所有用法,except后面还能跟表达式的。

所谓的表达式,就是错误的定义。也就是说,我们可以捕捉一些我们想要捕捉的异常。而不是什么异常都报出来。

异常分为两类:

  • python标准异常
  • 自定义异常

我们先抛开自定义异常(因为涉及到类的概念),看看 except 都能捕捉到哪些 python 标准异常。

请查看:Python 异常处理

2.1.2 try…finallly 语句

用于无论执行过程中有没有异常,都要执行清场工作。

try:  execution block  # 正常执行模块  
except A:  exc A block # 发生A错误时执行  
except B:  exc B block # 发生B错误时执行  
except:  other block # 发生除了A,B错误以外的其他错误时执行  
else:  if no exception, jump to here # 没有错误时执行  
finally:  final block  # 总是执行  

tips: 注意顺序不能乱,否则会有语法错误。如果用 else 就必须有 except,否则会有语法错误。

try:a = 1 / 2print(a)print(m)  # 抛出 NameError异常, 此后的语句都不在执行b = 1 / 0print(b)c = 2 / 1print(c)
except NameError:print("Ops!!")  # 捕获到异常
except ZeroDivisionError:print("Wrong math!!")
except:print("Error")
else:print("No error! yeah!")
finally:  # 是否异常都执行该代码块print("Successfully!")

代码分析:

  1. try 块开始。
  2. a = 1 / 2:这行代码是合法的,所以 a 被赋值为 0.5
  3. print(a):输出 0.5
  4. print(m):这行代码尝试打印变量 m,但在此之前没有定义 m,所以会抛出一个 NameError 异常。
  5. 由于在 try 块中抛出了 NameError 异常,所以会跳到相应的 except 块。该块捕获到异常并输出 “Ops!!”。
  6. 由于异常已经被捕获,后面的代码(包括 b = 1 / 0print(b)c = 2 / 1 和 print(c))都不会执行。
  7. 跳过 else 块(因为有一个被捕获的异常)。
  8. 进入 finally 块,并输出 “Successfully!”。

总结:

  • 当运行此代码时,输出将是:
0.5 
Ops!! 
Successfully!
  • 注意:尽管有 b = 1 / 0 和 c = 2 / 1,但它们不会被执行或输出,因为前面的 NameError 异常已被捕获。

说完上面两个概念,我们再来说说 with…as…语句。with…as…是从Python2.5引入的一个新的语法,它是一种上下文管理协议,目的在于从流程图中把 try,except 和finally 关键字和资源分配释放相关代码统统去掉,简化try...except...finlally的处理流程。

2.2 with…as…工作原理

with…as…语句相当于下面这段代码:

try:  # 尝试打开名为'example.txt'的文件,模式为'r',表示只读模式。  f = open('example.txt','r')  
except:  # 如果在尝试打开文件时发生任何异常(例如文件不存在),则执行此块。  print('fail to open')  # 打印错误消息,告知用户无法打开文件。  exit()  # 终止程序。  
else:  # 如果打开文件成功,则尝试读取文件内容并打印  print(f.read())finally:  # 不论是否发生异常,最后都会执行此块。  f.close()  # 关闭文件。这一步很重要,因为它确保文件资源被正确释放。

这是不是很麻烦,但正确的方法就是这么写。
我们为什么要写finally,是因为防止程序抛出异常最后不能关闭文件,但是需要关闭文件有一个前提就是文件已经打开了。

相关文章:

Python 之进阶语法:with...as...

1. Python with…as…是什么 Python 的 with…as… 语句,就像一个贴心的管家,负责照顾你的资源,让你不再担心忘记关闭文件、网络连接或数据库事务等。这个管家在你进入“房间”时自动打开门,离开时帮你把门关上,真的是…...

嵌入式硬件设计知识详解

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...

计算机网络:物理层 —— 信道及其极限容量

文章目录 信道信道的极限容量信号失真失真类型产生信号失真的主要因素 奈式准则码元传输速率香农公式 信道 信道是指信息传输的通道或介质。在通信中,信道扮演着传输信息的媒介的角色,将发送方发送的信号传递给接收方。 信道可以是无线信道&#xff0c…...

面向对象特性中 继承详解

目录 概念: 定义: 定义格式 继承关系和访问限定符 基类和派生类对象赋值转换: 继承中的作用域: 派生类的默认成员函数 继承与友元: 继承与静态成员: 复杂的菱形继承及菱形虚拟继承: 虚…...

C++ | Leetcode C++题解之第455题分发饼干

题目&#xff1a; 题解&#xff1a; class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int m g.size(), n s.size();int count 0;for (int i 0, j 0; i < …...

java版基于Spring Boot + Mybatis在线招投标|评标|竞标|单一采购|询价|邀标|在线开标|招标公告发布|评审专家|招投标采购系统源码

一、项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;…...

Anaconda的安装与环境设置

文章目录 一、Anaconda介绍二、Anaconda环境搭建1. 下载Anaconda(1)官网下载(2)清华大学镜像 2. 安装Anaconda3.配置环境变量4.检验conda是否安装成功5.更改镜像源6.若菜单栏没有conda prompt 三、虚拟环境1.创建、查看、删除虚拟环境2.激活、退出虚拟环境 四、CUDA、Pytorch、…...

使用FastAPI做人工智能后端服务器时,接口内的操作不是异步操作的解决方案

在做AI模型推理的接口时&#xff0c;这时候接口是非异步的&#xff0c;但是uvicorn运行FastAPI时就会出现阻塞所有请求。 这时候需要解决这个问题&#xff1a; api.py&#xff1a; import asyncio from fastapi import FastAPI from fastapi.responses import StreamingResp…...

Leetcode 3312. Sorted GCD Pair Queries

Leetcode 3312. Sorted GCD Pair Queries 1. 解题思路2. 代码实现 题目链接&#xff1a;3312. Sorted GCD Pair Queries 1. 解题思路 这一题的话坦率来说没有搞定&#xff0c;后来是找的大佬的代码抄了一下…… 整体来说这道题思路上还是比较暴力的&#xff0c;还是一个二重…...

用 Delphi 做了一个简单的 CMS

Delphi 代码上面花的时间最少。 前提是你要熟悉 Delphi 的 WebBroker 框架。不熟悉也没关系&#xff0c;5分钟就可以入门&#xff0c;10分钟就熟悉了。 CMS 就是个基于 WEB 的内容管理嘛。相当于一个简单的没有跟贴功能的 BBS。这样的东西&#xff0c;后边是数据库&#xff0…...

ASK, PSK, FSK, DPSK

ASK, PSK, FSK, DPSK详解&#xff1a; 这四种调制方式都是数字调制技术&#xff0c;用于将数字信号转换成适合在信道上传输的模拟信号。它们的主要区别在于如何用模拟信号的变化来表示数字信息。 1. ASK (Amplitude Shift Keying) 幅移键控: 原理: ASK 通过改变载波信号的幅…...

【Linux】认识Linux内核中进程级别的文件结构体【files_struct】&文件IO模型初步演示

前言 大家好吖&#xff0c;欢迎来到 YY 滴 系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Linux》…...

[Offsec Lab] ICMP Monitorr-RCE+hping3权限提升

信息收集 IP AddressOpening Ports192.168.52.218TCP:22,80 $ nmap -p- 192.168.52.218 --min-rate 1000 -sC -sV -Pn PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.9p1 Debian 10deb10u2 (protocol 2.0) | ssh-hostkey: | 2048 de:b5:23:89:bb:9f:d4:1…...

Studying-多线程学习Part4 - 异步并发——async future、packaged_task、promise

异步并发——async future packaged_task promise 1.async、future 是C11引入的一个函数模版&#xff0c;用于异步执行一个函数&#xff0c;并返回一个future对象&#xff0c;表示异步操作的结果。使用 async 可以方便地进行异步编程&#xff0c;避免了手动创建线程和管理线程…...

【Java基础】用Scanner类获取控制台输入

目录 Scanner类是什么导入并创建读取一个数读取字符串读取一行读取直到空白字符为止读取多个数直到^z读取一个字符 Scanner类是什么 在Java中&#xff0c;Scanner 是一个非常有用的类&#xff0c;用于从各种输入源&#xff08;如键盘、文件或其他输入流&#xff09;读取数据。…...

微服务seata解析部署使用全流程

官网地址&#xff1a; Seata 是什么&#xff1f; | Apache Seata 1、Seata术语 用来管理分布式事务&#xff0c;由阿里巴巴出品。 【1、TC (Transaction Coordinator) - 事务协调者】 用来维护事务的&#xff0c;包括主事务和分支事务。 【2、TM (Transaction Manager) - …...

Linux性能调优技巧

目录 前言1. CPU性能优化1.1 调整CPU调度策略1.2 合理分配多核处理 2. 内存性能优化2.1 调整内存分配策略2.2 缓存和分页优化 3. 磁盘I/O性能优化3.1 使用合适的I/O调度器3.2 磁盘分区和文件系统优化 4. 网络性能优化4.1 优化网络参数4.2 调整网络拥塞控制算法 5. 系统监控与优…...

python 实现sha1算法

sha1算法介绍 SHA-1&#xff08;Secure Hash Algorithm 1&#xff0c;安全散列算法1&#xff09;是一种密码散列函数&#xff0c;由美国国家安全局&#xff08;NSA&#xff09;设计&#xff0c;并由美国国家标准技术研究所&#xff08;NIST&#xff09;发布为联邦数据处理标准…...

ejb-ref元素

ejb-ref 是用于在 Java EE (现在称为 Jakarta EE) 中引用 Enterprise JavaBeans (EJB) 的一个元素&#xff0c;主要用于定义和配置 SLEE (Service Logic Execution Environment) 组件中的 EJB 依赖关系。通过这个引用&#xff0c;SBB (Service Building Block) 可以轻松地访问和…...

Perl 子程序(函数)

Perl 子程序&#xff08;函数&#xff09; Perl 是一种高级、解释型、动态编程语言&#xff0c;广泛用于CGI脚本、系统管理、网络编程、 finance, bioinformatics, 以及其他领域。在Perl中&#xff0c;子程序&#xff08;也称为函数&#xff09;是组织代码和重用代码块的重要方…...

ElasticSearch 备考 -- Snapshot Restore

一、题目 备份集群下的索引 task&#xff0c;存储快照名称为 snapshot_1 二、思考 这个涉及的是集群的备份&#xff0c;主要是通过创建快照&#xff0c;涉及到以下2步骤 Setp1&#xff1a;注册一个备份 snapshot repository Setp2&#xff1a;创建 snapshot 可以通过两种方…...

【Linux】进程替换、命令行参数及环境变量(超详解)

目录 进程替换 替换函数的含义 命令行参数 环境变量 PATH 进程替换 我们先看代码&#xff1a; 1 #include<stdio.h>2 #include<unistd.h>3 int main()4 {5 printf("process...begin!\n");6 7 execl("/usr/bin/ls","ls"…...

MySQL事务日志—redo日志介绍

MySQL事务日志—redo日志 事务有4种特性&#xff1a; 原子性、一致性、隔离性和持久性。 那么事务的四种特性到底是基于什么机制实现? 事务的原子性、一致性由事务的 undo 日志事务的隔离性由锁机制和MVCC实现。事务的持久性由redo 日志来保证。 两类日志概述&#xff1a;…...

告别音乐小白!字节跳动AI音乐创作工具,让你一键变作曲家!

还在羡慕别人能创作动听的音乐&#xff1f;五音不全的你&#xff0c;也梦想着谱写属于自己的乐章&#xff1f;现在&#xff0c;机会来了&#xff01;字节跳动推出了一款AI音乐创作工具——抖音推出的海绵音乐&#xff0c;它能让你轻松一键创作音乐&#xff0c;即使是“音乐小白…...

空心正方形图案

KiKi学习了循环&#xff0c;BoBo老师给他出了一系列打印图案的练习&#xff0c;该任务是打印用“*”组成的“空心”正方形图案。 输入描述&#xff1a; 多组输入&#xff0c;一个整数(3~20)&#xff0c;表示输出的行数&#xff0c;也表示组成正方形边的“ * ”的数量。 输出描述…...

【EXCEL数据处理】000020 案例 保姆级教程,附多个操作案例。EXCEL使用表格。

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【EXCEL数据处理】000020 案例 保姆级教程&#xff0c;附多个操作案例。…...

虾皮Shopee大数据面试题及参考答案

Cube 表性能优化,还有其他优化的方法吗? Cube 表性能优化可以从多个方面入手。 一方面,可以优化数据存储格式。选择合适的存储格式能够减少存储空间占用,提高数据读取速度。例如,Parquet 格式是一种高效的列式存储格式,它可以按列进行数据压缩,大大减少磁盘 I/O 和内存占…...

重学SpringBoot3-集成Redis(六)之消息队列

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;六&#xff09;之消息队列 1. 什么是发布/订阅&#xff08;Pub/Sub&#xff09;&#xff1f;2. 场景应用3. Spring Boot 3 整合 R…...

LeetCode 134 Gas Station 解题思路和python代码

题目&#xff1a; There are n gas stations along a circular route, where the amount of gas at the ith station is gas[i]. You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from the ith station to its next (i 1)th station. You …...

服务攻防

171、一次完整的 HTTP 请求过程 域名解析 --> 发起 TCP 的 3 次握手 --> 建立 TCP 连接后发起 http 请求 --> 服务器 响应 http 请求&#xff0c;浏览器得到 html 代码 --> 浏览器解析 html 代码&#xff0c;并请求 html 代码中的资源&#xff08;如 js、 css…...