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

分类: 计算机技术
推荐阅读:
Python 列表(List)的详细用法 列表(list)按特定顺序存储一系列项目。你可以使用索引或在循环中访问项。本问讲述了Python中列表的增加、修改、删除、遍历、复制等基本操作。
Python exec()函数 Python中的exec函数用于动态执行Python代码。它接受一个包含Python代码的字符串作为参数,并将其作为Python程序执行。
Python hash()函数 在 Python 中,hash() 函数用于获取给定对象的哈希值(散列值),即对象的唯一标识符。
C语言islower()函数:判断字符是否为小写字母 islower()是C语言标准库中的一个函数,用于检查一个字符是否为小写字符;如果传入的字符参数是小写字母,则返回非0值,否则返回0;
Python tuple()函数 tuple() 函数用于将一个可迭代对象转换为元组,其语法如下:
MATLAB使用误差扩散法进行图像半色调处理 误差扩散法(Error Diffusion)是一种常用的图像半色调处理方法,它的基本思想是通过将误差扩散到周围的像素点来逐渐逼近目标灰度值,从而实现图像半色调处理的效果。