对象支持上下文管理协议 (with 语句)

Python - with 对异常处理的优化 (上下文管理应用) 目录 零、让对象支持上下文管理协议 一、上下文管理的简单执行流程 二、错误执行流程 三、异常处理 with 应用 四、raies 和 raise……from 的区别 零、让对象支持上下文管理协议 上下文管理协议:context-management protocol ,通过 with 语句触发。 只要对象内实现 __enter__() 和 __exit__() 方法,就能兼容 w... 阅读详情

方式一:

为了让一个对象兼容 with 语句,你需要实现 __enter__ () 和 __exit__ () 方法。例如,考虑如下的一个类,它能为我们创建一个网络连接:

# -*- coding: utf-8 -*-
"""
上下文管理器协议 with 语句

————enter————
————exit————
"""
from functools import partial
from socket import socket, AF_INET, SOCK_STREAM


class LazyConnection:

    def __init__(self, address, family=AF_INET, type=SOCK_STREAM):
        self.address = address
        self.family = family
        self.type = type
        self.sock = None

    def __enter__(self):   # with open(...) as fp: 调用这个方法,返回值就是fp
        if self.sock is not None:
            raise RuntimeError('Already connected')
        self.sock = socket(self.family, self.type)
        self.sock.connect(self.address)
        return self.sock

    def __exit__(self, exc_ty, exc_val, tb):  # 不管正常还是异常,都调用这个方法,关闭套接字
        self.sock.close()
        self.sock = None


conn = LazyConnection(('www.python.org', 80))

with conn as s:
    s.send(b'GET /index.html HTTP/1.0\r\n')
    s.send(b'Host: www.python.org\r\n')
    s.send(b'\r\n')
    resp = b''.join(iter(partial(s.recv, 8192), b''))
    print(resp)



编写上下文管理器的主要原理是你的代码会放到 with 语句块中执行。 当出现 with语句的时候,对象的 __enter__ () 方法被触发,它返回的值 (如果有的话) 会被赋值给as 声明的变量。然后, with 语句块里面的代码开始执行。最后, __exit__ () 方法被触发进行清理工作(释放资源)。

不管 with 代码块中发生什么,上面的控制流都会执行完,就算代码块中发生了异常也是一样的。事实上, __exit__ () 方法的三个参数包含了异常类型、 异常值和追溯信息 (如果有的话)。 __exit__ () 方法能自己决定怎样利用这个异常信息,或者忽略它并返回一个 None 值。如果 __exit__ () 返回 True ,那么异常会被清空,就好像什么都没发生一样, with 语句后面的程序继续在正常执行。

还有一个细节问题就是 LazyConnection 类是否允许多个 with 语句来嵌套使用连接。很显然,上面的定义中一次只能允许一个 socket 连接,如果正在使用一个 socket的时候又重复使用 with 语句,就会产生一个异常了。不过你可以像下面这样修改下上面的实现来解决这个问题:


class LazyConnection:
    def __init__(self, address, family=AF_INET, type=SOCK_STREAM):
        self.address = address
        self.family = family
        self.type = type
        self.connections = []

    def __enter__(self):
        sock = socket(self.family, self.type)
        sock.connect(self.address)
        self.connections.append(sock)
        return sock

    def __exit__(self, exc_ty, exc_val, tb):
        self.connections.pop().close()


conn = LazyConnection(('www.python.org', 80))
with conn as s1:
    pass
    with conn as s2:
        pass

在第二个版本中, LazyConnection 类可以被看做是某个连接工厂。在内部,一个列表被用来构造一个栈。每次 __enter__ () 方法执行的时候,它复制创建一个新的连接并将其加入到栈里面。 __exit__ () 方法简单的从栈中弹出最后一个连接并关闭它。这里稍微有点难理解,不过它能允许嵌套使用 with 语句创建多个连接,就如上面演示的那样。

在需要管理一些资源比如文件、网络连接和锁的编程环境中,使用上下文管理器是很普遍的。这些资源的一个主要特征是它们必须被手动的关闭或释放来确保程序的正确运行。例如,如果你请求了一个锁,那么你必须确保之后释放了它,否则就可能产生死锁。通过实现__enter__ () 和 __exit__ () 方法并使用 with 语句可以很容易的避免这些问题,因为 __exit__ () 方法可以让你无需担心这些了。

方式二:

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

在使用 @contextmanager 装饰的生成器中,yield 语句的作用是把函数的定义体分成两部分:yield 语句前面的所有代码在 with 块开始时(即解释器调用 __enter__ 方法时)执行,yield 语句后面的代码在 with 块结束时(即调用 __exit__ 方法时)执行。

# -*- coding: utf-8 -*-
"""
更改输出流
"""
import contextlib


@contextlib.contextmanager  # 应用 contextmanager 装饰器。
def looking_glass():
    import sys
    original_write = sys.stdout.write  # 贮存原来的 sys.stdout.write 方法

    def reverse_write(text):  # 定义自定义的 reverse_write 函数;在闭包中可以访问 original_write
        original_write(text[::-1])

    sys.stdout.write = reverse_write  # 把 sys.stdout.write 替换成 reverse_write

    # 产出一个值,这个值会绑定到 with 语句中 as 子句的目标变量上。执行 with 块中的代
    # 码时,这个函数会在这一点暂停
    yield 'JABBERWOCKY'

    # 控制权一旦跳出 with 块,继续执行 yield 语句之后的代码;这里是恢复成原来的 sys.stdout.write 方法。
    sys.stdout.write = original_write


if __name__ == '__main__':
    with looking_glass() as what:
        print('what', what)
        # YKCOWREBBAJ

    print(what)
    # JABBERWOCKY


错误与异常之上下文管理 从上面的错误我们可以看出, float() 对不合法的参数很不客气. 例如, 如果参数的类型正确(字符串), 但值不可转换为浮点数, 那么将引发 ValueError 异常, 因为这是值的错误. 列表也是不合法的参数, 因为他的类型不正确, 所以, 引发一个 TypeError 异常.​我们现在给出一个交互操作的例子 - 从最基本的错误检测开始, 然后逐步改进它, 增强代码的健壮性. 这里的问题是把一个用字符串表示的数值转换 为正确的数值表示形式, 而且在过程中要检测并处理可能的错误. 阅读详情

相关推荐

Python基础: with模式和__enter__ 和 __exit__

有一些任务,可能事先需要设置,事后做清理工作。 with方法就是python的非常酷的语句,安全可靠,方便。我们自己的类如何具备with的能力?必须拥有__enter__()方法,另一个__exit__(),因此,这里介绍这些能力。

gongdiwudu的专栏 3620

让对象支持上下文管理协议

问题 你想让你的对象支持上下文管理协议(with语句)。 解决方案 为了让一个对象兼容 with 语句,你需要实现 enter() 和 exit() 方法。 例如,考虑如下的一个类,它能为我们创建一个网络连接: from socket import socket, AF_INET, SOCK_STREAM class LazyConnection: def __init__(self, ...

YOYO的博客 246

面板数据分析中的随机前沿软件FRONTIER Version 4.1应用

随机前沿模型是一种用于评估单位效率的统计方法。它考虑了输入和输出的随机性,允许我们在效率评估中引入不确定性。随机前沿模型通常用于评估生产单位、金融机构、医院等各种类型的决策单元的效率。FRONTIER是一个广泛使用的随机前沿分析软件,具有用户友好的界面和强大的功能。它提供了估计效率、前沿分析和模型比较的工具,使用户能够深入研究单位的效率和绩效。面板数据是一种包含多个单位(通常是时间序列数据)的数据类型,可以用于分析单位在不同时间点的变化和效率。

目标检测专栏持续更新中,改进YOLO系列通用,适用v5、v7、v8、所有博客均是团队原创博客,所有文章禁止转载,违者必究。 2981

[00803]让对象支持上下文管理协议

让对象支持上下文管理协议一、 解决问题 想让对象支持上下文管理协议(with语句)。 二、解决方案 重新–enter–(), –exit–() 让对象能够兼容with语句,比如:获取资源和释放资源的类 三、代码说明#!/usr/bin/env pythonfrom socket import socket, AF_INET, SOCK_STREAMclass LazyConnecti

语言小蛀虫 337

Linux 音频驱动(六) ALSA音频驱动之PCM Write数据传递过程

目录1. 前言2. PCM Data Flow3. 总结 1. 前言 本文,我们将以回放(Playback,播放音频)为例,讲解PCM Data是如何从用户空间到内核空间,最后传递到Codec。 在Linux 音频驱动(一) ASoC音频框架简介中,我们给出了回放(Playback)PCM数据流示意图: 对于Linux来说,由于分为 user space 和kernel space,而且两者之间不能随便互相访问。因此用户如果播放音频,则需要调用copy_from_user()将用户数据从user spa

_Modest_的博客 1万+

Jetson Orin NX上PyTorch环境搭建与性能优化指南

本文详细指导如何在Jetson Orin NX上搭建高效的PyTorch开发环境。内容涵盖CUDA与cuDNN的“隐藏”配置、Miniconda虚拟环境管理、PyTorch for Jetson的正确安装与验证,并提供了电源模式设置、TensorRT加速、混合精度等关键性能优化实战技巧,帮助开发者充分释放边缘AI设备的算力。

weixin_29090089的博客 337

python-让对象支持上下文管理协议

【代码】python-让对象支持上下文管理协议。

sinat_25495131的博客 619

STM32实现简单的智能电子相框

具体的代码案例和详细的代码实现超过5000字,无法在此篇文章中提供。但是,你可以参考STM32的官方文档和相应的图形库和多媒体库的文档,以获得更详细的实现细节和代码示例。对于硬件,我们可以选择使用STM32开发板,如STM32F4 Discovery。对于软件开发环境,我们将使用Keil MDK-ARM作为开发工具,并使用STM32CubeMX进行代码配置。在本文中,我们将使用STM32单片机实现一个简单的智能电子相框,包括显示照片、播放视频和音乐功能。接下来,我们将详细描述实现智能电子相框的步骤。

2401_85625565的博客 1005

上下文管理协议

用到了两个系统内置函数__enter__ __exit__ 如果想象打开文件那样来操作类的实例化对象,则必须在类里面写入上面两个方法,事实上通过with……as的方式实例化出来对象的值是通过__enter__的返回值来赋值的,enten在对象实例化的那一步会被触发,而exit则会在with里面的流程结束时触发 实现代码如下: 1 class Sto: 2 def ...

weixin_30496431的博客 109

BMP390L数字大气压传感器原理图设计,已量产(压力传感器)

在工业设备的室内定位、地下设施监测这类 GPS 信号盲区场景里,气压高度检测的 “靠谱程度” 直接决定了系统的可用性 —— 毕竟谁也不想在地下停车场导航时,设备把 1 楼误判成 3 楼。最近在项目里基于博世 BMP390L 做了硬件电路设计,正好聊聊这款工业级数字气压传感器的硬实力,以及原理图里的那些关键设计细节。

不脱发的程序猿 349

华为MetaERP的交易计税模块(即“税务引擎”)在设计上确实受到Oracle E-Business Tax(EBTax)等国际先进税务架构理念的影响,但结合了华为自身全球化运营、多准则合规、高并发处

华为MetaERP税务引擎在借鉴Oracle EBTax三层架构基础上,创新升级为五层智能税务架构,实现从"税码驱动"到"场景+规则+AI驱动"的转变。该模块采用云原生微服务架构,支持全球190+国家税务规则动态加载,具备实时计税、多准则并行处理、AI风险预警等核心能力,深度适配金税工程等国内合规要求。通过税务数字孪生、RPA机器人等创新,形成自主可控的智能税务中枢,为跨国企业提供全栈国产化税务解决方案,重新定义ERP税务管理范式。

金牌架构师 114

让对象支持上下文管理协议:深入理解Python with语句的原理与实践

让对象支持上下文管理协议:深入理解Python with语句的原理与实践

KE17RS的博客 756

AIGC游戏开发:如何评估生成内容的玩家满意度?

如何量化评估生成内容对玩家体验的影响?本文聚焦AIGC生成的游戏内容(包括但不限于剧情、关卡、NPC对话、道具),系统探讨玩家满意度的评估方法论,覆盖主观与客观评估、静态与动态内容、短期与长期体验等场景。核心概念:定义AIGC与玩家满意度的关联维度;评估方法:主观(问卷/访谈)与客观(行为/生理数据)评估的技术细节;数学模型:构建多指标融合的评估模型;实战案例:以AIGC生成关卡为例,演示从数据采集到模型落地的全流程;工具资源:推荐数据采集、分析与建模的工具链;

AI天才研究院 1223

with语句处理异常这份足够了

with语句处理异常 我们知道使用try-except-finally语句可以处理异常,接下来我们介绍使用with语句处理与异常相关的工作 with语句支持创建资源,抛出异常,释放资源等操作,并且代码简洁。 with语句格式 with 上下文表达式 [as 资源对象]: 对象操作 说明: 上下文表达式返回一个上下文管理对象 如果指定了as语句,该对象并不赋值给as子句中的资源对象,而是将上下文管...

weixin_33921089的博客 444

YOLOv8改进 | 注意力篇 | 一文带你改进GAM、CBAM、CA、ECA等通道注意力机制和多头注意力机制

官方论文地址:官方论文地址点击此处即可跳转官方代码地址:官方代码地址点击此处即可跳转GAM旨在通过设计一种机制,减少信息损失并放大全局维度互动特征,从而解决传统注意力机制在通道和空间两个维度上保留信息不足的问题。GAM采用了顺序的通道-空间注意力机制,并对子模块进行了重新设计。具体来说,通道注意力子模块使用3D排列来跨三个维度保留信息,并通过一个两层的MLP增强跨维度的通道-空间依赖性。

Snu77的博客 4万+

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

python语言基础-5 进阶语法-5.5 上下文管理协议(with语句)

声明:本内容非盈利性质,也不支持任何组织或个人将其用作盈利用途。本内容来源于参考书或网站,会尽量附上原文链接,并鼓励大家看原文。侵删。

qq_29567799的博客 355

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Python 上下文管理器

contextlib模块实现上下文自动管理,生成器可以用更简单的方法创建上下文管理器。

qq_60271706的博客 566

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

python语言原理_Python之with语句原理

我们看一个with处理文件操作的实例:with open('/etc/passwd') as f:for line in f:print(line)这段代码的作用:打开一个文件,如果一切正常,把文件对象赋值给f,然后用迭代器遍历文件中每一行,当完成时,关闭文件;而无论在这段代码的任何地方,如果发生异常,此时文件仍会被关闭。with看起来如此简单,但是其背后还有一些工作要做,因为你不能对Python...

weixin_39692253的博客 85

python之with ... as ... 语句

基础知识:上下文管理协议(Context Management Protocol):包含方法 __enter__() 和 __exit__(),支持该协议的对象要实现这两个方法。上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了__enter__() 和 __exit__() 方法。上下文管理器定义执行 with 语句时要建立的运行时上下文,负责执行 with...

yanhuangzhinu0的专栏 242

python 之 with-as

python with-as

Dayu_log的博客 5792

python上下文管理协议_Python3 - 让对象支持上下文管理协议

问题让对象支持上下文管理协议,兼容with语句。解决方案为了让一个对象兼容 with 语句,需要实现 __enter__() 和__exit__() 方法。 例如,考虑如下的一个类,它能为我们创建一个网络连接:from socket import socket, AF_INET, SOCK_STREAMclass LazyConnection(object):def __init__(self, ...

weixin_31673213的博客 199

python with使用介绍

with。

琅嬛福地 1614

Python的上下文管理

1.1什么是上下文管理器上下文管理器是一个包装任意代码块的对象,上下文管理器保证1.进入上下文管理器时,每次代码执行的一致性2.当退出上下文管理器时,相关的资源会被正确地回收(即使内部代码出错,退出步骤也会执行)。1.2上下文管理器的应用上下文管理器被用到最多的就是——作为确保资源正确清理的一种方式。.........

cylcylccyyll的博客 214

7-3 如何让对象支持上下文管理协议,需要定义__enter__, __exit__方法 分别在with开始和结束时候被调用

7-3 如何让对象支持上下文管理 解决方案: 实现上下文管理协议,需要定义enter, exit方法 他们分别在with开始和结束时候被调用with TelnetClient2('127.0.0.1') as client: client.start() 对象client是来自于__enter__函数的返回 最后退出的时候不管是否存在异常,都将会进入到__exit__处理wi

ben1949的专栏 700
上一篇: python functools.partial 减少某个函数的参数个数
下一篇: c++ 11 auto、decltype比较
MZP_man
博客等级 码龄8年 188粉丝 145原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值