Python里with语句的用法与技巧

本文将详细讲解Python语言中with语句的用法,以及如何让自定义的类也支持with语句;

先看一段Python读取文件的代码:

class TooBig(Exception):pass

fp = open("text.txt",'r')
data = fp.read()
fp.close()
if len(data) > 10:
    raise TooBig
    
print(data)

这段代码如果使用with关键字,能大大提升阅读性:

class TooBig(Exception):pass

with open("text.txt",'r') as fp:
    data = fp.read()
    if len(data) > 10:
        raise TooBig

print(data)

with是如何实现的

with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的清理操作,释放资源,比如文件使用后自动关闭、线程锁中的自动获取和释放等;

python中有两个特殊的方法构成上下文管理协议,分别是__enter____exit__;要让自定义的类支持with语句,需要定义并实现它们;

class test:
    def __init__(self, name):
        self.name = name
        print("__init__")

    def say(self):
        print("hello,",self.name)

    def __enter__(self):
        print("__enter__")
        return self   #可以返回不同的对象

    def __exit__(self, exc_type, exc_value, exc_tb):
        
        print("__exit__")
        if exc_tb:
            print("exited with exception raised.")
        else:
            print("exited without exception.")

with test("iKun") as k:
    k.say()
    #raise Exception

程序运行结果:

__init__
__enter__
hello, iKun
__exit__
exited without exception.

test类中的__enter__()方法返回的是自身的引用,这个引用可以赋值给as子句中的k变量(也可省略);返回值的类型可以根据实际需要设置为不同的类型,不必是上下文管理器对象本身。

线程锁的应用

with语句也尝尝用于线程锁的使用上:

import threading
lock= threading.Lock()

#lock.acquire()
#pass
#lock.release()

with lock:
    pass

其他参考

更多上下文管理器的高级用法,请参考contextlib模块中的contextmanage装饰器、nested函数和closing上下文管理器;

这些对象,可以对已有的生成器函数或对象进行包装,加入对上下文管理器协议的支持,避免了专门编写上下文管理器来支持with语句。

原创内容,如需转载,请注明出处;

本文地址: https://www.perfcode.com/p/502.html

分类: 计算机技术
推荐阅读:
IDLE是什么? IDLE是Python的一个集成开发与学习环境(Integrated Development and Learning Enviroment);与Python捆绑在一起,安装好Python以后,IDLE会自动安装;它使用Python 和Tkinter Gui编写。
近期WordPress更新失败以及官网无法打开原因 在WordPress后台进行更新,尝试多次均发生了 429 Too Many Requests 错误。起初以为是当前WordPress更新用户较多导致的,随后几天发现大多数用户还是无法更新,且错误都为429,且WordPress的官网也无法打开,返回429错误。
Implementation of the USB 2.0 controller not found!解决方案 你可能在使用VirtualBox启动虚拟机系统时碰到“不能为虚拟电脑打开一个新的任务”的错误提示,并提示 Implementation of the USB 2.0 controller not found!
Linux下快速的重命名文件 在Linux系统下,不知道你们是怎么重命名文件的,虽然方法很多,但我这个绝对是最简单且最高效的,而且只有一条命令就可实现:
Python breakpoint()函数详细教程 brekpoint()函数是python3.7版本新增的一个内置函数;该函数会在调用时使程序进入调试器中;
C语言toupper()函数:将字符转换成大写 toupper()是C语言标准库中的一个函数,用于将一个字符转换成对应的大写形式;如果传入的字符参数是一个小写字母,tolower()函数会返回其对应的大写字母;如果参数不是小写字母,则原封不动的返回;