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

分类: 计算机技术
推荐阅读:
Rust解析YAML,结构体序列化和反序列化 serde_yaml 是 Rust 的一个 crate,提供了支持将数据结构序列化为 YAML 格式,以及将 YAML 格式反序列化为 Rust 数据结构的功能。
Python计算圆周率,精确到n位 本文将使用Python计算圆周率,可精确到n位,n值越大精度越高。
Python zip()函数 zip() 函数用于将多个可迭代对象中的元素按顺序一一对应打包成一个个元组,返回一个可迭代的 zip 对象。
Windows和Linux系统启用IP转发 在Windows系统下启用IP转发,需要通过修改注册表来实现;Linux系统只需将系统下的/proc/sys/net/ipv4/ip_forward文件值修改为1;
Linux显示使用内存最多的十个进程 在Linux系统下,你可以使用一条命令显示当前系统使用内存最多的十个进程:
如何查看CPU的出厂日期 通常情况下,CPU的出厂日期是写在CPU的标签或者包装盒上的。如果您已经安装了CPU,则可以通过操作系统或者第三方软件来查看CPU的出厂日期。以下是一些方法: