iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python3,浅谈with的神奇魔法
  • 449
分享到

python3,浅谈with的神奇魔法

浅谈神奇魔法 2023-01-31 01:01:43 449人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

在实际的编码过程中,有时有一些任务,需要事先做一些设置,事后做一些清理,这时就需要python with出场了,with能够对这样的需求进行一个比较优雅的处理,最常用的例子就是对访问文件的处理。 一般访问文件资源时我们会这样处理: f

在实际的编码过程中,有时有一些任务,需要事先做一些设置,事后做一些清理,这时就需要python with出场了,with能够对这样的需求进行一个比较优雅的处理,最常用的例子就是对访问文件的处理。

一般访问文件资源时我们会这样处理:


f = open(r'c:\test.txt', 'r')
data = f.read()
f.close()

这样写没有错,但是容易犯两个毛病:
1. 如果在读写时出现异常而忘了异常处理。
2. 忘了关闭文件句柄

以下的加强版本的写法:


f = open(r'c:\test.txt', 'r')
try:
    data = f.read()
finally:
    f.close()

以上的写法就可以避免因读取文件时异常的发生而没有关闭问题的处理了。代码长了一些。
但使用with有更优雅的写法:


with open(r'c:\test.txt', 'r') as f:
    data = f.read()

说明:
with后面接的对象返回的结果赋值给f。此例当中open函数返回的文件对象赋值给了f.with会自已获取上下文件的异常信息。
with是如何做到的呢?
with后面返回的对象要求必须两__enter__()/__exit__()这两个方法,而文件对象f刚好是有这两个方法的,故应用自如。
pytho中官方定义说明如下(https://docs.Python.org/2/reference/datamodel.html#context-managers):


object.__enter__(self)
进入与此对象相关的运行时上下文。with语句将将此方法的返回值绑定到语句的AS子句中指定的目标(如果有设置的话)

object.__exit__(self, exc_type, exc_value, traceback)
退出与此对象相关的运行时上下文。参数描述导致上下文退出的异常。如果上下文运行时没有异常发生,那么三个参数都将置为None。
如果有异常发生,并且该方法希望抑制异常(即阻止它被传播),则它应该返回True。否则,异常将在退出该方法时正常处理。

请注意, __exit__()方法不应该重新抛出传入的异常,这是调用者的职责。

下面举例说明他的原理:

1. 无异常发生时的例子:


#!/user/bin/env python3
#-*- coding:utf-8 -*-

class Test:
    def __enter__(self):
        print('__enter__() is call!')
        return self

    def dosomething(self):
        print('dosomethong!')

    def __exit__(self, exc_type, exc_value, traceback):
        print('__exit__() is call!')
        print(f'type:{exc_type}')
        print(f'value:{exc_value}')
        print(f'trace:{traceback}')
        print('__exit()__ is call!')

with Test() as sample:
    sample.dosomething()

>>
__enter__() is call!
dosomethong!
__exit__() is call!
type:None
value:None
trace:None
__exit()__ is call!

以上的实例Text,我们注意到他带有__enter__()/__exit__()这两个方法,当对象被实例化时,就会主动调用__enter__()方法,任务执行完成后就会调用__exit__()方法,另外,注意到,__exit__()方法是带有三个参数的(exc_type, exc_value, traceback), 依据上面的官方说明:如果上下文运行时没有异常发生,那么三个参数都将置为None, 这里三个参数由于没有发生异常,的确是置为了None, 与预期一致. 

2. 有异常发生时,会抛出异常的例子:
以下例子在上面稍做了一些修改,让运行时产生异常,看看这三个参数的赋值情况:


#!/user/bin/env python3
#-*- coding:utf-8 -*-

class Test:
    def __enter__(self):
        print('__enter__() is call!')
        return self

    def dosomething(self):
        x = 1/0
        print('dosomethong!')

    def __exit__(self, exc_type, exc_value, traceback):
        print('__exit__() is call!')
        print(f'type:{exc_type}')
        print(f'value:{exc_value}')
        print(f'trace:{traceback}')
        print('__exit()__ is call!')
        # return True


with Test() as sample:
    sample.dosomething()
>>
__enter__() is call!
Traceback (most recent call last):
__exit__() is call!
type:<class 'ZeroDivisionError'>
  File "C:/Users/xxx/PyCharmProjects/Test1/test.py", line 23, in <module>
value:division by zero
    sample.dosomething()
trace:<traceback object at 0x000001C08CF32F88>
  File "C:/Users/xxx/PycharmProjects/Test1/test.py", line 10, in dosomething
__exit()__ is call!
    x = 1/0
ZeroDivisionError: division by zero

从结果可以看出, 在执行到dosomethong时就发生了异常,然后将异常传给了__exit__(), 依据上面的官方说明:如果有异常发生,并且该方法希望抑制异常(即阻止它被传播),则它应该返回True。否则,异常将在退出该方法时正常处理。当前__exit__并没有写明返回True,故会抛出异常,也是合理的,但是正常来讲,程序应该是不希望它抛出异常的,这也是调用者的职责,我们将再次修改__exit__, 将其返回设置为True, 

3. 有异常发生时,不再抛出异常的例子:


在上面的例子上做点修改.
#!/user/bin/env python3
#-*- coding:utf-8 -*-

class Test:
    def __enter__(self):
        print('__enter__() is call!')
        return self

    def dosomething(self):
        x = 1/0
        print('dosomethong!')

    def __exit__(self, exc_type, exc_value, traceback):
        print('__exit__() is call!')
        print(f'type:{exc_type}')
        print(f'value:{exc_value}')
        print(f'trace:{traceback}')
        print('__exit()__ is call!')
        return True


with Test() as sample:
    sample.dosomething()

>>
__enter__() is call!
__exit__() is call!
type:<class 'ZeroDivisionError'>
value:division by zero
trace:<traceback object at 0x000001C94E592F88>
__exit()__ is call!

从结果看,异常抛出被抑制了,符合预期。
 

--结束END--

本文标题: python3,浅谈with的神奇魔法

本文链接: https://www.lsjlt.com/news/184693.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python3,浅谈with的神奇魔法
    在实际的编码过程中,有时有一些任务,需要事先做一些设置,事后做一些清理,这时就需要python with出场了,with能够对这样的需求进行一个比较优雅的处理,最常用的例子就是对访问文件的处理。 一般访问文件资源时我们会这样处理: f ...
    99+
    2023-01-31
    浅谈 神奇 魔法
  • 浅谈Python魔法方法
    特殊方法一览 在 Python 的学习和使用过程中, 你一定碰到过一些 特殊方法, 它们开头和结尾都有两条下划线, 也叫魔法方法 (Magic method), 或者 Dunder...
    99+
    2024-04-02
  • 浅谈一下Python中的with用法
    目录一、With语句是什么二、with如何工作三、相关术语一、With语句是什么 有一些任务,可能事先需要设置,事后做清理工作。对于这种场景,Python的with语句提供了一种非常...
    99+
    2023-05-15
    Python with Python with用法
  • 浅谈C++/C关于#define的那些奇奇怪怪的用法
    目录前言1 缩减代码 2 定义变量3 代替函数 4 函数做不到的功能5 一些有些"邪门"的用法 6 与#define有关联的带&ld...
    99+
    2024-04-02
  • node.js 操作系统模块的魔法:化腐朽为神奇
    文件和目录操作:揭开存储的奥秘 该模块赋予开发者对文件和目录的完全操控权。它提供了一系列函数,用于创建、读取、写入、删除和管理文件,以及创建、移动和删除目录。通过这种能力,开发人员可以构建各种应用程序,包括文件管理工具、数据存储解决方案和...
    99+
    2024-04-02
  • 魔幻的分页世界:ASP DataPager 的神奇之旅
    一、什么是 ASP DataPager? ASP DataPager 是 ASP.NET 控件,用于在 Web 应用程序中处理数据分页。它允许用户在大量数据集的页面之间轻松导航,从而提高应用程序的可用性和用户体验。 二、DataPage...
    99+
    2024-03-02
    ASP.NET、DataPager、分页、Web 应用程序
  • 浅析 JavaScript 事件处理的神奇魅力
    JavaScript 事件处理是一种非常实用的技术,它可以通过将事件与元素关联起来,并在事件发生时执行相应的代码来实现各种各样的交互效果。在本文中,我们将详细探讨 JavaScript 事件处理的原理和使用方法,并通过一些示例代码来展示...
    99+
    2024-02-22
    JavaScript 事件处理 事件监听器 事件类型 事件对象 事件冒泡
  • 缓存的魔法:释放 ASP 页面片段缓存的神奇力量
    ASP 页面片段缓存的原理 片段缓存允许您将页面或页面部分存储在服务器内存中,从而避免每次请求都从数据库或文件系统加载。这对于频繁访问或静态的内容至关重要,因为可以显着减少服务器处理和数据传输时间。 片段缓存的优势 提高性能: 减少数...
    99+
    2024-03-05
    ASP.NET、缓存、片段缓存、性能、优化
  • 浅谈Python3中打开文件的方式(Withopen)
    目录0.背景知识1.常规方式:读取文件-----open()2.推荐方式:读取文件-----With Open1).读取方式2).常见的坑3).跳过第一行内容(字段名)3.写入内容-...
    99+
    2024-04-02
  • 浅谈replaceAll的用法
    replaceAll是一个字符串的方法,用于替换字符串中的指定字符或字符序列。它的用法如下:1. replaceAll(String...
    99+
    2023-09-09
    replaceAll
  • 操作系统文件系统魔法:管理文件的神奇艺术
    作为操作系统的一个基本组件,文件系统决定了文件如何存储、组织和检索,并提供了一套与文件进行交互的接口。它使您可以创建、删除、读取和写入文件,而无需了解底层存储设备的复杂性。文件系统是现代计算的基础,也是理解操作系统的工作方式的关键。 文...
    99+
    2024-02-11
    文件系统 操作系统 文件管理 存储 组织 检索
  • PHP数组的一些神奇魔法:Git和LeetCode是如何帮助你的?
    作为一名PHP开发人员,你可能已经知道了PHP中的数组是多么的强大和灵活。但是,你是否真正了解PHP数组的一些神奇魔法呢?本文将介绍一些PHP数组的高级用法,并介绍如何使用Git和LeetCode来提高你的PHP编程技能。 数组的引用传...
    99+
    2023-08-13
    数组 git leetcode
  • Python 包管理器的神奇世界:发现它的魔力
    包管理器概览 包管理器充当了 Python 软件包的分发平台。它们托管大量经过预先编译和测试的软件包,涵盖各种功能,从数据科学到 Web 开发。主要包管理器包括: pip: 官方的 Python 包管理器,用于安装和管理 Python ...
    99+
    2024-04-02
  • 揭示框架标签的神奇魔力:超越网页的界限
    框架标签,一个在网页布局中至关重要的元素,它允许开发者在单个网页中划分多个子区域,每个子区域都可以加载独立的内容。框架标签的神奇魔力不仅限于创建复杂的布局,还延伸到了超越网页界限的众多领域,增强了网站的可访问性和响应能力。 模块化设计:...
    99+
    2024-02-29
    框架标签、网页布局、响应式设计、网站可访问性
  • Git的神奇魔法!Java程序员如何利用Git来提高代码质量?
    Git是目前最流行的版本控制工具之一,它为开发人员提供了强大的工具来管理和维护代码库。对于Java程序员来说,Git可以帮助我们提高代码质量,保证代码的稳定性和可维护性。本文将介绍Git的一些神奇魔法,以及如何使用Git来提高Java程序员...
    99+
    2023-11-08
    leetcode numy git
  • 浅谈MultipartFile中transferTo方法的坑
    前言:最近用SpringBoot写文件上传功能,使用参数绑定之后确实是非常的方便了。 但是,项目部署就出现了问题,搞得我一脸懵逼。 后来,才发现是因为我使用了相对路径导致的,这个绝对...
    99+
    2024-04-02
  • 浅谈C#中[]的几种用法
    目录一、导入外部DLL函数二、结构体时表明属性一、导入外部DLL函数 如[DllImport(“kernel32.dll”)]这叫引入kernel32.dll...
    99+
    2023-01-28
    C# []用法 C# []
  • 浅谈springboot之JoinPoint的getSignature方法
    JoinPoint的getSignature方法 在使用springboot写aop的时候,有个JoinPoint类,用来获取代理类和被代理类的信息。 这个文章记录一下JoinPoi...
    99+
    2024-04-02
  • 浅谈Vue3中watchEffect的具体用法
    前言 watchEffect,它立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。 换句话说:watchEffect相当于将watch 的依赖源...
    99+
    2024-04-02
  • 浅谈Java常见的排序算法
    目录一、直接插入排序二、希尔排序三、冒泡排序四、快速排序五、选择排序(Selection Sort)六、堆排序七、归并排序一、直接插入排序 基本思想: 将一个记录插入到已排序的有序表...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作