Python教程:with ... as 语句你懂嘛?

Python 之进阶语法:with...as... 是从Python2.5引入的一个新的语法,它是一种上下文管理协议,目的在于从流程图中把 try,except 和finally 关键字和资源分配释放相关代码统统去掉,简化try...except...finlally的处理流程。我们发现,一旦跳入了某条except语句,就会执行相应的异常处理方法(block),执行完毕就会结束。–>发现B错误,开始寻找匹配B的异常处理方法,发现A,跳过,发现except others(即except:),执行exc other block。所谓的表达式,就是错误的定义。 阅读详情

说到 with 大家通常看到的应该是这样的:

示例 1

with open('courses.txt') as f:
    for i in f:
        print(i.strip())

打开一个文件,然后循环做一些事情。但是你知道为什么会有 with 吗?我们自己是不是能够写出可以作用在 with 关键字上的对象呢?

现在,我们带着上述两个问题来说一说 with 的由来以及上下文管理器相关内容。

with 语句的目的是简化 try/finally 模式。这种模式用于保证一段代码运行完毕后执行某项操作,即便那段代码由于异常、return 语句或sys.exit() 调用而中止,也会执行指定的操作。finally 子句中的代码通常用于释放重要的资源,或者还原临时变更的状态。

示例1的功能我们可以使用 try/finally 模式实现:

示例2

try:
    f = open('courses.txt')
    for i in f:
        print(i.strip())
finally:
    f.close()

try中的 except 和 else 不是必须的,这里为了简单明了,我们只用了 finally。

对比两个示例,我们可以看到示例1相对简洁,这就是 with 的由来。

其实,语言中的一些特性或者说一些亮眼的特性,必然是有一个演化的过程的,我们作为后来者和使用者应该多花一些心思去思索其背后的实现过程,相信你会收获更多。

那么 上下文管理器 又是什么呢?

上下文管理器协议包含 __enter__ 和 __exit__ 两个方法。with 语句开始运行时,会在上下文管理器对象上调用__enter__方法。with 语句运行结束后,会在上下文管理器对象上调用__exit__方法,以此扮演 finally 子句的角色。最常见的例子是确保关闭文件对象(示例1)。

下面我们实现一个简单的例子来直观的感受一下:

class T:
    def __enter__(self):
        print('T.__enter__')
        return '我是__enter__的返回值'
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('T.__exit__')

with T() as t:
    print(t)

输出:

T.__enter__
我是__enter__的返回值
T.__exit__

示例3中实现了一个类T,它的对象包含了__enter__和__exit__方法,有了这两个方法就可以使用 with 处理该对象。执行 with 后面的表达式T()得到的是上下文管理器对象,通过as字句把对象绑定到了变量t上。

观察输出结果,可以看到with块先调用了__enter__方法,在处理完内部逻辑(print(t))之后调用了exit方法,而t其实就是__enter__方法的返回值。

当然,这个例子只是为了方便我们理解上下文管理器,下面我们看一个更有意思的例子:

示例4

obj1 = HaHa('你手机拿反了')
with obj1 as content:
    print('哈哈镜花缘')
    print(content)
print('#### with 执行完毕后,再输出content: ####')
print(content)

输出:

缘花镜哈哈
了反拿机手你
#### with 执行完毕后,在输出content: ####
你手机拿反了

示例4中,上下文管理器是 HaHa 类的实例,Python 调用此实例的__enter__方法,把返回结果绑定到 变量content 上。

打印一个字符串,然后打印 content 变量的值。可以看到打印出的内容都是是反向的。

最后,当 with 块已经执行完毕。可以看出,__enter__ 方法返回的值——即存储在 content 变量中的值——是字符串 ‘你手机拿反了’。
输出不再是反向的了。

HaHa类的实现:

import sys

class HaHa:

    def __init__(self, word):
        self.word = word

    def reverse_write(self, text):
        self.original_write(text[::-1])

    def __enter__(self):
        self.original_write = sys.stdout.write
        sys.stdout.write = self.reverse_write
        return self.word

    def __exit__(self, exc_type, exc_value, traceback):
        sys.stdout.write = self.original_write
        return True

在__enter__方法中,我们接管了标准输出,将其替换成我们自己编写的方法reverse_write,reverse_write方法将参数内容反转。而在__exit__方法中,我们将标准输出还原。__exit__方法需要返回True。

总之,with之于上下文管理器,就像for之于迭代器一样。with就是为了方便上下文管理器的使用。

上下文管理器特性在标准库中有一些应用:

在 sqlite3 模块中用于管理事务;

在 threading 模块中用于维护锁、条件和信号;

另外,说到上下文管理器就不得不提一下@contextmanager 装饰器,它能减少创建上下文管理器的样板代码量,因为不用编写一个完整的类,定义 __enter__和 __exit__ 方法,而只需实现有一个 yield 语句的生成器,生成想让 __enter__ 方法返回的值。

在使用 @contextmanager 装饰的生成器中,yield 语句的作用是把函数的定义体分成两部分:

  • yield 语句前面的所有代码在 with 块开始时(即解释器调用 __enter__ 方法时)执行

  • yield 语句后面的代码在with 块结束时(即调用 __exit__ 方法时)执行。

下面我们用 @contextmanager 装饰器来实现一下示例4的功能:

示例5

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
import sys
import contextlib

@contextlib.contextmanager
def WoHa(n):
    original_write = sys.stdout.write
    def reverse_write(text):
        original_write(text[::-1])
    sys.stdout.write = reverse_write
    yield n
    sys.stdout.write =  original_write
    return True

obj1 = WoHa('你手机拿反了')
with obj1 as content:
    print('哈哈镜花缘')
    print(content)
print('#### with 执行完毕后,在输出content: ####')
print(content)

输出:

缘花镜哈哈
了反拿机手你
#### with 执行完毕后,在输出content: ####
你手机拿反了

这里我们需要注意的是:代码执行到yield时,会产出一个值,这个值会绑定到 with 语句中 as 子句的变量上。执行 with 块中的代码时,这个函数会在yield这里暂停。此时,相当于示例4中执行完__enter__方法。而控制权一旦跳出 with 块(块内代码执行完毕)则继续执行 yield 语句之后的代码。

@contextmanager 装饰器优雅且实用,把三个不同的 Python 特性结合到了一起:函数装饰器、生成器和 with 语句。

现在,我想你应该能够解答开篇提到的两个问题了吧!

100天精通Python(基础篇)——第24天:with...as语句介绍 1. 为什么要使用with...as语句? 2. with语句是什么 3. with语句的作用 4. with语句工作原理 5. with语句自动处理异常 阅读详情

相关推荐

【Python入门】5大Python with-as 语句技巧:你真的用对了吗?

with-aswith-as语句(上下文管理器)是一种简洁的语法,用于确保资源(如文件、网络连接等)在使用后能够正确地释放。即使在代码块中发生异常,资源也会被正确释放。自定义上下文管理器需要实现__enter__和__exit__方法。with-aswith-as定义:自定义上下文管理器通过实现__enter__和__exit__方法,管理自定义资源。作用:自定义上下文管理器可以管理更复杂的资源,提供更灵活的资源管理机制。with-aswith-as亲爱的小伙伴们,今天的课程就到这里啦!通过学习这些。

java专栏 1168

python with as用法详解

任何一门编程语言中,文件的输入输出、数据库的连接断开等,都是很常见的资源管理操作。但资源都是有限的,在写程序时,必须保证这些资源在使用过后得到释放,不然就容易造成资源泄露,轻者使得系统处理缓慢,严重时会使系统崩溃。 例如,前面在介绍文件操作时,一直强调打开的文件最后一定要关闭,否则会程序的运行造成意想不到的隐患。但是,即便使用 close() 做好了关闭文件的操作,如果在打开文件或文件操作过程中抛出了异常,还是无法及时关闭文件。 为了更好地避免此类问题,不同的编程语言都引入了不同的机制。在python中..

tecoes的博客 1万+

数字IC后端实战:OCC电路时钟树综合的5个关键技巧(附Synopsys工具配置)

本文深入探讨了数字IC后端设计中OCC电路时钟树综合的实战技巧。针对工具自动平衡导致的绕线拥塞和时序问题,文章提出了分段处理的核心思路,并详细阐述了通过物理隔离、分段长树策略以及Synopsys工具链(如ICC2、PrimeTime)的精准配置来优化function clk与occ clk路径的关键方法,旨在提升时序收敛性和可制造性。

jwt8token的博客 854

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

with...as...是从Python2.5引入的一个新的语法,它是一种上下文管理协议,目的在于从流程图中把 try,except 和finally 关键字和资源分配释放相关代码统统去掉,简化。Python 的 with...as... 语句,就像一个贴心的管家,负责照顾你的资源,让你不再担心忘记关闭文件、网络连接或数据库事务等。这个管家的工作方式很简单,你只需要在 with 后面跟上你要管理的资源,然后在 as 后面给这个资源起个名字。在Python中,任何数字除以0都是未定义的,所以会引发这个错误。

moment159的博客 5048

Unity嵌套ScrollView滑动冲突解决方案:ExecuteEvents.Execute事件透传

在Unity UGUI中,竖向与横向ScrollView嵌套时出现滑动失效,本质是EventSystem事件分发机制的拦截限制。其原理在于PointerDown被外层捕获后,后续PointerMove默认不向下透传;ExecuteEvents.Execute提供了一条绕过常规冒泡流程的官方事件旁路,支持低延迟、方向自适应的精准透传。该技术具备高兼容性与零侵入特性,广泛应用于电商商品页、内容流卡片组、多级导航等需‘列表中嵌套轮播/标签’的真实场景,是解决UGUI嵌套滚动问题的核心工程实践方案。

weixin_33164198的博客 629

六轴机械臂正逆解计算

机械臂运动学就是。包括(Forward Kinematics)和(InverseKinematics)两部分。正运动学就是逆运动学则是关节变量->机械臂末端执行器的姿势=正向运动学机械臂未端执行器的位姿->关节变量=逆向运动学。

gaoxiaochan的博客 1万+

python中with...as的用法

文章内容主要部分来至:http://www.360doc.com/content/16/0905/16/25664332_588595085.shtml with…as,就是个python控制流语句,像 if ,while一样。 with…as语句是简化版的try except finally语句。 那我们先理解一下try…except…finally语句是干啥的。实际上,try…exc

琪琪的博客 14万+

基于STM32的智能衣柜系统开发实战(附完整源码与硬件设计)

本文详细介绍了基于STM32的智能衣柜系统开发实战,包括硬件设计、软件架构和云端功能实现。系统具备实时温湿度监控、自动加热除湿、紫外线杀菌等核心功能,通过STM32F103C8T6主控芯片和ESP8266无线模块实现智能控制。附完整源码与硬件设计,适合科技爱好者和开发者参考。

peach的博客 780

Python基础教程: with语句详解

with语句的应用场景 编程中有很多操作都是配套使用的,这种配套的流程可以称为计算过程,Python语言为这种计算过程专门设计了一种结构:with语句。比如文件处理就是这类计算过程的典型代表。 使用with语句前后对比 没有使用with语句之前,我们是这样打开一个文件的: try: # 1. [进入] f = open('a.txt', 'r', encoding="utf-8") # 2. [执行] print(f.read()) finally: if f:

Python热爱者的博客 1万+

Open3D 计算点云的主曲率

本文介绍了点云主曲率计算的方法与实现。通过分析曲面局部几何形状的主曲率(最大和最小方向),基于法线构建投影矩阵和协方差矩阵,使用奇异值分解计算曲率。代码采用Open3D实现,包括点云加载、法线估计、邻域搜索和曲率映射可视化功能。系统支持交互式点云文件选择,将曲率值映射为色彩进行直观展示,为点云处理中的特征提取和分割任务提供基础几何特征。实现过程包含了法线去中心化、协方差矩阵构建和特征值归一化等关键步骤,完整展示了从理论到实践的曲率分析流程。

点云侠的博客 543

路径规划 | 图解RRT*算法(附ROS C++/Python/Matlab仿真)

RRT*算法针对传统RRT算法进行了渐进最优改进,在添加节点到搜索树的过程中进行重连选择。本文图解RRT*算法原理,并采用ROS C++、Python、Matlab三种语言实现算法,加深理解

FRIGIDWINTER的博客 9404

深入理解Python的With-as语句

学习Python有一段时间了,最近做一个项目会涉及到文件的读取和关闭。比如:我想把一些对象序列化到文件里面,然后当我再次使用的时候,在从文件里面读取反序列化成对象。像这种操作一般都是用try…except…finally。但是经过自己对Python的研究发现会有更出色的方法,比如:with-as语句也有的人称为context manager。 With-as 用法 我们先看一下例子,当我们需要...

ctrigger的专栏 2792

【QCA6174】QCA6174 DFS认证的时候会有概率信道不会跳转的情况,通常跳转成功概率只有25%问题分析及解决方案

Master设备需要测试的项目。

wgl307293845的博客 752

python中with as 用法

with as和try except finally语句

朱克莱尔的学习记录 5884

【FISCO BCOS】二十、多机部署区块链

实际开发中,为了满足高可用性和高容错性的需求,往往会采用多级部署区块链的方式,今天介绍一下FISCO BCOS的多机部署流程。

naihe_fish的博客 3648

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Python的With...As 语句:优雅管理资源的技术探索

在Python编程中,`with...as`语句是一项强大而优雅的功能,用于管理资源,如文件、网络连接、数据库连接等。本文将深入介绍`with...as`语句的用法、其工作原理,并通过代码示例解析其实际应用。`with...as`语句是Python中一种上下文管理器的使用方式,主要用于在进入和退出特定代码块时执行必要的操作。最常见的用法是处理资源的分配和释放,确保在离开代码块时资源被正确关闭或释放。

一键难忘的博客 5132

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

python学习之【with语句】

python的with语句的原理及使用

沃和莱特的博客 8498

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Python中with…as语句如何使用?Python中with…as语句的详细用法

但是有很多的小伙伴对它的使用还不是特别的了解,所以今天的这篇文章就带大家一起来学习了解一下,文章内容清晰,操作简单,一起来学习一下吧。2、在语句使用的时候,如果是一个[]包括的部分表示可以使用或省略。在这个语法中,我们可以看到在表达式的后面跟的是一对中括号,就表示里面的参数是一个可以使用也可以忽略的参数,不需要使用到变量的时候,target也可以不用定义。1、使用这个语句时,我们可以对上下文进行管理的操作,它还能帮我们自动的分配内存,同时还可以将我们不需要的资源进行释放,以免造成不必要的资源浪费。

Python栈_基的博客 1639

Python 中with…as语句

Python 中with…as语句 @(Python基础知识)[Python, with…as, 解析] 通常在Python的使用中,大家经常看到with…as语句有这样的用法: with open('test.txt') as f: f.read() 而正如大家所看到的Python中关于with…as语句的用法最多的也是在对文件的操作中,那么with关键字到底是怎样进行操作的...

我的博客 1万+

python 之 with-as

python with-as

Dayu_log的博客 5792

Python中的with…as…语法

1、使用with....as...的原因: python操作文件时,需要打开文件,最后手动关闭文件。 通过使用with...as...不用手动关闭文件。当执行完内容后,自动关闭文件。 2、先说明一个常见问题,文件打开: try: f = open('xxx') do something except: do something finally: f.c...

mingyuli的博客 2万+

python的with as语句_python学习之with...as语句

python中的with...as...语句类似于try...finally...语句:# -*- coding: utf-8 -*-#"""with...as...语句"""#try...finally...语句f = open('data.txt')try:data = f.read()print(data)finally:f.close()#with...as...语句with open('...

weixin_39747577的博客 205

python with as语句_python with (as)语句实例详解

python with (as)语句实例详解这篇文章主要介绍了python with (as)语句实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。例1:url = 'http://w...

weixin_39942213的博客 804

python中with as的作用,python中with用法及原理, python中with as 用法

with as 呢,就是个python控制流语句,像 if ,while。with as 语句的结构:with expression [as variable]:with-blockwith expresion as variable的执行过程是首先执行_enter_函数,它的返回值会赋给as后面的variable,想让它返回什么就返回什么,只要你知道怎么处理就可以了,如果不写as variabl...

weixin_32687311的博客 1076
上一篇: Python教程:迭代器的正确使用方法
下一篇: Python教程:推荐一个比 open 读文件还好用、方便的库
Python热爱者
博客等级 码龄7年 3049粉丝 1330原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值