Python3中上下文管理器介绍
在任何编程语言中,文件操作或数据库连接等资源的使用都很常见。但这些资源供应有限。因此,主要问题在于确保在使用后释放这些资源。如果不释放它们,则会导致资源泄漏,并可能导致系统变慢或崩溃。如果用户有一个自动设置和拆卸资源的机制,这将是非常有帮助的。在Python3中,可以通过使用上下文管理器(context manager)来实现,这有助于正确处理资源。上下文管理器是一个对象。
在Python3中,可以通过上下文管理器来管理资源。可通过三种方式创建上下文管理器:基于类的上下文管理器、基于生成器的上下文管理器和基于函数装饰器的上下文管理器。
当使用类创建上下文管理器时,用户需要确保该类具有__enter__()和__exit__()方法。__enter__()返回需要管理的资源;而__exit__()不返回任何内容,而是执行清理操作。
上下文管理器通常使用with语句调用,但也可以通过直接调用它们的方法来使用。上下文管理器定义了在执行with语句时要建立的运行时上下文,它处理进入(entry into)和退出(exit from)所需的运行时上下文以执行代码块。
执行文件操作的最常见方式是使用with关键字。Python的with语句支持由上下文管理器定义的运行时上下文的概念。这是使用一对方法(__enter__, __exit__)实现的,这些方法允许用户自定义的类在语句体执行之前进入并在语句结束时退出的运行时上下文。
with语法:
with EXPRESSION [as TARGET]:SUITE
with语句执行过程如下:
(1).评估上下文表达式以获得上下文管理器;
(2).上下文管理器的__enter__()被加载以备后用;
(3).上下文管理器的__exit__()被加载以备后用;
(4).上下文管理器的__enter__()方法被调用;
(5).如果TARGET包含在with语句中,则将__enter__()的返回值赋值给它。with语句保证如果__enter__()方法没有错误返回,那么__exit__()将始终被调用。因此,如果在赋值给TARGET列表的过程中发生错误,它将被视为SUITE中发生的错误。__enter__()方法既可以带有返回值也可以不带返回值,若不带返回值则默认返回None。
(6).SUITE被执行;
(7).上下文管理器的__exit__()方法被调用。如果异常导致SUITE退出,则其类型、值和回溯(traceback)将作为参数传递给__exit__();否则,传递3个None。__exit__()方法也是可以带返回值的,这个返回值应该是一个布尔类型True或False,默认为None(即False)。如果为False,异常会被抛出,用户需要进行异常处理。如果为True,则表示忽略该异常。
如果SUITE因异常退出,并且__exit__()方法返回的值为False,则触发异常。如果返回值为True,则异常被抑制,并继续执行with语句之后的语句。
如果SUITE因异常以外的任何原因退出,则__exit__()的返回值将被忽略,并在所采取的退出类型的正常位置继续执行。
contextmanager.__enter__():输入运行时上下文并返回此对象或与运行时上下文相关的另一个对象。此方法返回的值绑定到使用此上下文管理器的with语句的as子句中指定的目标(如果有)。返回自身的上下文管理器的一个示例是文件对象。文件对象从__enter__()返回自身以允许open()用作with语句中的上下文表达式。
contextmanager.__exit__(exc_type, exc_val, exc_tb):退出运行时上下文并返回一个布尔标志,指示是否应抑制发生的任何异常。如果在执行with语句主体时发生异常,则参数包含异常类型、值和回溯信息(traceback information)。否则,所有三个参数都是None。从此方法返回True将导致with语句抑制异常并继续执行紧跟在with语句之后的语句。否则,此方法执行完毕后,异常将继续传播。执行此方法期间发生的异常将替换with语句主体中发生的任何异常。传入的异常不应显式重新引发,相反,此方法应返回False以指示该方法成功完成并且不想抑制引发的异常。这允许上下文管理代码轻松检测__exit__()方法是否实际失败。
上下文管理器的典型用途包括保存和恢复各种全局状态、锁定和解锁资源、关闭打开的文件等。
何时使用上下文管理器:当你的代码必须打开和关闭连接作为其流程的一部分时;当你的代码必须使用前置条件和后置条件(preconditions and post-conditions)时;以及当你尝试管理系统上的有限资源时,上下文管理器是一个不错的选择。
以上内容主要参考:
1. https://docs.python.org/3/reference/datamodel.html#context-managers
2. https://www.geeksforgeeks.org/context-manager-in-python/
以下为测试代码:
import contextlibvar = 3if var == 1:# reference: https://www.geeksforgeeks.org/context-manager-in-python/# 基于类的上下文管理器class FileManager():def __init__(self, filename, mode):self.filename = filenameself.mode = modeself.file = Nonedef __enter__(self):self.file = open(self.filename, self.mode)return self.filedef __exit__(self, exc_type, exc_value, exc_traceback):self.file.close()# loading a filewith FileManager('test.txt', 'w') as f:f.write('Test')print(f.closed) # True
elif var == 2:# https://medium.com/swlh/3-ways-to-create-context-managers-in-python-a88e3ba536f3# 基于生成器的上下文管理器:代替__enter__和__exit__方法,生成器和@contextlib.contextmanager装饰器将在yield语句之前运行所有内容,就好像它是__enter__方法的一部# 分一样,产生的值可能是__enter__方法将返回的结果.之后,将运行with块中的内容,作为最后一步,将运行yield语句之后的代码,就好像它是__exit__方法一样@contextlib.contextmanagerdef file_hanlder(file_name, file_mode):file = open(file_name, file_mode)print("open file")yield file # yeild之前的代码会在上下文管理器中作为__enter__方法执行,并将结果通过yield返回,所有在yield之后的代码会作为__exit__方法执行file.close()print("close file")with file_hanlder("test.txt", "w") as f:f.write("Test2")print("write file")print(f.closed) # True
elif var == 3:# https://medium.com/swlh/3-ways-to-create-context-managers-in-python-a88e3ba536f3# 基于函数装饰器的上下文管理器:函数装饰器方法的问题之一是无法访问__enter__方法的返回值class file_handler_mixin(contextlib.ContextDecorator):def __init__(self, file_name, file_mode):self._file_name = file_nameself._file_mode = file_modeself._file = Nonedef __enter__(self):print(f"Enter Method: File Name {self._file_name}")self._file = open(self._file_name, self._file_mode) # 无法从装饰函数访问文件对象return self._filedef __exit__(self,exc_type,exc_value,exc_traceback):print(f"Exit Method: File Mode {self._file_mode}")self._file.close()@file_handler_mixin("test.txt", "w")def write_to_file():print("Not access to the value returned by the __enter__ method")write_to_file()print("test finish")
GitHub:https://github.com/fengbingchun/Python_Test
相关文章:
LatentFusion:华盛顿大学与英伟达联合提出6D姿态估计新方法
作者 | Keunhong Park、Arsalan Mousavian、Yu Xiang、Dieter Fox 译者 | 刘畅 编辑 | Jane 出品 | AI科技大本营(ID:rgznai100) 【导读】在本文中,华盛顿大学和英伟达联合提出了一种新的用于未见过目标 6D姿态估计的框架。作…

Java前端控制器模式
前端控制器模式(Front Controller Pattern)是用来提供一个集中的请求处理机制,所有的请求都将由一个单一的处理程序处理。该处理程序可以做认证/授权/记录日志,或者跟踪请求,然后把请求传给相应的处理程序。以下是这种…

提供第三种代码生成方式——通过自定义BuildProvider为ASP.NET提供代码生成
2019独角兽企业重金招聘Python工程师标准>>> 之前写了一些关于代码生成的文章,提供了两种不同方式的代码生成解决方案,即CodeDOMCustom Tool和T4。对于ASP.NET应用,你还有第三种选择——自定义BuildProvider。[文中涉及的源代码从…

Java拦截过滤器模式
拦截过滤器模式(Intercepting Filter Pattern)用于对应用程序的请求或响应做一些预处理/后处理。定义过滤器,并在把请求传给实际目标应用程序之前应用在请求上。过滤器可以做认证/授权/记录日志,或者跟踪请求,然后把请…

1200亿次日均位置服务响应、20亿公里日均轨迹里程,百度地图发布新一代人工智能地图生态全景
12月10日,百度地图首次公布了“新一代人工智能地图”生态全景。目前,百度地图日均位置服务请求次数突破1200亿次,日均轨迹里程20亿公里,注册开发者数量达180万,服务超过50万个移动应用。 百度地图事业部总经理李莹称&…

Python3中global/nonlocal用法
全局变量(global variable)是那些未在任何函数内部定义并且具有全局作用域的变量,而局部变量(local variable)是那些在函数内部定义并且其作用域仅限于该函数的变量。换句话说,我们可以说局部变量只能在初始化它的函数内部访问,而全局变量在整…

客户端动态调用WCF服务中的方法
首先要写一个执行动态调用的方法:在里面实现反射调用。 public static object ExecuteMethod<T>(string pUrl,string pMethodName, params object[] pParams) { EndpointAddress address new EndpointAddress(pUrl); Binding bindinginstance null; NetTcpB…

Python3中闭包介绍
Python3中的闭包(closure)是一个函数对象,它记住封闭作用域(enclosing function)中的值,即使它们不存在于内存中。它是一个将函数与环境一起存储的记录。由于闭包用作回调函数,因此它们提供了某种数据隐藏,这有助于我们减少使用全…

Java服务定位器模式
服务定位器模式(Service Locator Pattern)用在我们想使用 JNDI 查询定位各种服务的时候。考虑到为某个服务查找 JNDI 的代价很高,服务定位器模式充分利用了缓存技术。在首次请求某个服务时,服务定位器在 JNDI 中查找服务ÿ…

用AI加速物联网落地,安富利的客户洞察和解决之道
作为一家全球IT解决方案分销商,成立于1921年的安富利也紧随AI浪潮,为区域和全球的终端客户提供AI解决方案。据了解,安富利已为全球超过1400家企业提供技术支持,电子产品年度出货量达1220亿片。 近日在媒体沟通会上,安富…

Linux运维工程师发展前景
随着IT产业的不断发展,尤其是Linux行业的发展,现在互联网企业服务器数量越来越多,当到达几百台,上千台服务器之后,服务器日常管理也逐渐繁杂,每天如果通过人工去频繁的更新或者部署及管理这些服务器&#x…

Python3中__init__.py文件介绍
Python中的模块是包含Python定义和语句的文件(A module is a file containing Python definitions and statements),其文件名是模块名加后缀名.py。在模块内部,通过全局变量__name__可以获取模块名。 模块包含可执行语句及函数定义。这些语句用于初始化模…
赠书 | 熵的实际应用,赌场和金融圈最著名的一个数学公式
本文选自湛庐文化策划出版图书《模型思维》。作者斯科特佩奇,超过100万用户的“模型思维课”主讲人。密歇根大学复杂性研究中心“掌门人”。圣塔菲研究所外聘研究员。曾出版《多样性红利》一书。斯科特佩奇以对社会科学多样性和复杂性的研究和建模面闻名。具体研究方…

Java传输对象模式
传输对象模式(Transfer Object Pattern)用于从客户端向服务器一次性传递带有多个属性的数据。传输对象也被称为数值对象。传输对象是一个具有 getter/setter 方法的简单的 POJO 类,它是可序列化的,所以它可以通过网络传输。它没有…

图片下方出现几像素的空白间隙
1、如何定义高度很小的容器? 在IE6下无法定义小高度的容器,是因为有一个默认的行高。 列举2种解决方案:overflow:hidden | line-height:0 2、图片下方出现几像素的空白间隙? 这个也有多种解决方案,如将img定义为displa…

Python3中Pillow(PIL)介绍
PIL全称为Python Imaging Library,是Python中的免费开源图像处理库。PIL的最新版本为1.1.7,于2009年9月发布,支持Python的最高版本到2.7。原始的PIL开发于2011年停止。随后,一个名为Pillow的后续项目fork了PIL的repository并增加了…
GitHub有望在中国开设子公司?
作者 | Financial Times译者 | 弯月,编辑 | 郭芮出品 | CSDN(ID:CSDNnews)作为世界上最大的软件开发平台,GitHub 自去年被微软以 75 亿美元收购后,一直颇受外界的争议。虽然在交易完成后,GitHub…

OC指示符assign、atomic、nonatomic、copy、retain、strong、week的解释
在使用property定义property时可以在property与类型之间用括号添加一些额外的指示符,常用的指示符有assign、atomic、nonatomic、copy、retain、strong、week、等。详情如下: assign: 简单赋值,不更改索引计数(Referen…

项目沟通管理计划
沟通计划包括决定项目涉及人的信息和沟通需求:谁需要什么信息;什么时候需要;怎么获得。虽然所有的项目都需要沟通项目信息,但信息需求和传播方式差别很大。确认涉及人的信息需求和决定满足需求的适当方式是项目获得成功的重要因素…

PyTorch中torchvision介绍
TorchVision包包含流行的数据集、模型架构和用于计算机视觉的图像转换,它是PyTorch项目的一部分。TorchVison最新发布版本为v0.11.1,发布较频繁,它的license为BSD-3-Clause。它的源码位于: https://github.com/pytorch/vision T…
百度ERNIE登顶GLUE榜单,得分首破90大关
出品 | AI科技大本营(ID:rgznai100)12月10日,百度ERNIE在自然语言处理领域权威数据集GLUE中登顶榜首,以9个任务平均得分首次突破90大关刷新该榜单历史,其表现超越微软MT-DNN-SMART, 谷歌T5、ALBERT等一众顶级预训练模…

Java 重写(Override)与重载(Overload)
TestDog.java /* * 重写(Override) * 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写! * 重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现…

Oracle常用查看表结构命令
2019独角兽企业重金招聘Python工程师标准>>> select user from dual; //查看当前的用户名 select table_name from all_tables; //所有用户的表 select table_name from dba_tables; //包括系统表 select table_name from dba_tables where owner用户名 user_tabl…

TorchVision中使用FasterRCNN+ResNet50+FPN进行目标检测
TorchVision中给出了使用ResNet-50-FPN主干(backbone)构建Faster R-CNN的pretrained模型,模型存放位置为https://download.pytorch.org/models/fasterrcnn_resnet50_fpn_coco-258fb6c6.pth,可通过fasterrcnn_resnet50_fpn函数下载,此函数实现…

iOS-UIButton防止重复点击(三种办法)
目录 使用场景方法一 设置enabled或userInteractionEnabled属性方法二 借助cancelPreviousPerformRequestsWithTarget:selector:object实现方法三 通过runtime交换方法实现注意事项一 使用场景 在实际应用场景中,有几个业务场景需要控制UIButton响应事件的时间间隔。…
华为诺亚方舟开源预训练模型“哪吒”,4项任务均达到SOTA
出品 | AI科技大本营(ID:rgznai100)BERT之后,新的预训练语言模型XLnet、RoBERTa、ERNIE不断推出,这次,华为诺亚方舟实验室开源了基于BERT的中文预训练语言模型NEZHA(哪吒),寓意模型能…

音量调节助手(转)
源:音量调节助手 软件名称:音量调节助手 软件功能:通过键盘快捷键快速调节系统主音量 软件版本:V2014 软件作者:易几网络 操作系统:所有WINDOWS版本 开发工具:DELPHI XE …

TorchVision中通过AlexNet网络进行图像分类
TorchVision中给出了AlexNet的pretrained模型,模型存放位置为https://download.pytorch.org/models/alexnet-owt-4df8aa71.pth ,可通过models.alexnet函数下载,此函数实现在torchvision/models/alexnet.py中,下载后在Ubuntu上存放…
西湖龙井也上链?是的,以后你喝什么茶我都知道!
什么?区块链还可以帮忙法律取证?是的!就是这么牛13!区块链存证第一案12月9日,据《新华每日电讯》报道,杭州互联网法院用区块链提升审判效率。报道提到一个案例。2018年4月,杭州一家公司…

Java Enumeration接口
import java.util.Vector; import java.util.Enumeration; /* * Enumeration接口中定义了一些方法,通过这些方法可以枚举(一次获得一个)对象集合中的元素。 * 这种传统接口已被迭代器取代,虽然Enumeration 还未被遗弃࿰…