Python进阶-魔术方法(3)


3楼猫 发布时间:2024-08-12 14:27:36 作者:赢赢赢赢麻 Language

前言

前篇:

魔术方法(1):使用__str__与__repr__进行字符串操作

魔术方法(2):使用__iter__与__next__实现可迭代

正文

魔术方法(3):使用__enter__与__exit__创建上下文管理器

但凡写过Python的人,肯定不会对下列代码感到陌生,这也是Python里面我最喜欢的语法糖

如果你还接触过其他编程语言(比如C和Java),都会感叹Python语法的简单,因为我们不需要考虑文件的打开和关闭,也不需要封装异常处理,这是如何实现的?

Python进阶-魔术方法(3)-第0张

打开并读取一个文件

这正是上下文管理器的威力

所谓上下文管理器,也就是管理这一段代码周围其他代码的一个小工具,比如上文的as f中的f就是一个上下文管理器,他会控制我说的文件打开和关闭以及异常处理,这些都归功于__enter____exit__

专业点来说:

上下文管理器,即context manager,它是一个对象,定义了运行时的上下文,使用with语句来执行

实际上就是为该对象定义了一个时间段,在时间段开始的时候对做一件事情,在时间段结束的时候会做另外一件事情,在时间段开始和结束之间,可以使用该对象

----------分割----------

让我先给出一段示例代码,来展示这两个魔术方法的作用,请务必根据打印的步骤顺序,理解上下文管理器的执行顺序

Python进阶-魔术方法(3)-第1张

使用魔术方法实现一个定时器

Python进阶-魔术方法(3)-第2张

运行结果

只要一个类实现了__enter____exit__,我们就可以把它称为上下文管理器

  1. __enter__方法没有参数,返回值会交给with……as……进行绑定

    该方法主要用于安装上下文,返回管理器本身进行绑定

    上下文管理器对象遇到with语句后才会执行__enter__方法,这个方法的返回值会绑定给as后面的变量

  2. __exit__方法有三个参数,全部都是与异常相关的参数,当没有发生异常的时候,参数为None,我们可以通过参数类型来判断上下文管理器是否是正常结束,还是因为异常而结束,又是因为哪些异常。可以编写一系列异常类型判断来决定执行哪些操作

    该方法有一个返回值,是bool类型,如果为True会压制运行过程中的一切异常,反之不压制,我们可以主动制造异常(如抛出一个Exception)来验证这一点

    该方法主要用于清除(释放)对象

    当上下文管理器结束的时候会执行__exit__方法,用来处理异常与释放对象

----------分割----------

上下文管理器有着极为强大的功能,所以它是我最喜欢的Python语法

你可以依赖这两个方法实现许多操作,比如

  • 依靠__enter__实现用户权限的验证

  • 依靠__exit__实现文件、网络链接、数据库链接等重要资源的关闭

只要你处在上下文管理器的范围之内,哪怕你使用sys.exit(0)Ctrl+C这种强制结束应用的操作,也会顺利进入__exit__方法内部执行结束操作

在下列代码中,我使用sys.exit(0)强制结束这个程序,但是上下文管理器依然顽强的进入了__exit__,忠心耿耿地执行完整个关闭操作,我们可以清楚的看到打印的异常类型为SystemExit,也就是系统退出

正是由于这种强大的抗干扰能力,我们才能够在各种场合中使用with open语句来随意打开文件而不需要担心文件的关闭问题

Python进阶-魔术方法(3)-第3张

强大的异常应对能力


© 2022 3楼猫 下载APP 站点地图 广告合作:asmrly666@gmail.com