揭秘 Python 中的 with 关键字
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了揭秘 Python 中的 with 关键字相关的知识,希望对你有一定的参考价值。
参考技术A正文
你有没有想过 with 语句是什么以及我们为什么使用它呢?请阅读这篇文章!我们中的许多人在 Python 代码中一遍又一遍地看到这个代码片段: with open( \'Hi.text\' , \'w\' ) as f:
f.write( "Hello, there" )
但是,我们中的一些人不知道 with 有什么用,以及为什么我们需要在这里使用它。在此阅读中,您将找到关于 with 可解决的几乎所有问题。让我们开始吧!
首先,让我们考虑一下如果不使用 with 关键字我们需要做什么。在这种情况下,我们需要先打开文件并 尝试 执行 write 。不管成功与否,我们最好在 最后 关闭它,所以我们的代码将如下所示:
f = open( \'Hi.text\' , \'w\' )
try :
f.write( \'Hello, there\' )
finally :
f.close()
那么, with 关键字有什么用呢?它只是有助于将我们的 try..finally 代码缩短为 with... 的单个语句!这就是 with 语句用法。
那么,它到底是什么?事实上, with 语句本身在 Python 中并没有什么特别之处,它只是 Python 中 上下文管理器 的一个特性。 上下文管理器 ,引用自 Python 官方文档, 是一种让您在需要时准确分配和释放资源的方法 ,或者简单来说: 当您在某些资源上做某事时缩短您的代码片段 ,这意味着您可以自己定义 with 语句的用法!
我们如何做到这一点?嗯,很简单,你只需要实现两个 魔术函数 :一个叫做 __enter__ ,另一个叫做 __exit__ 。第一种方法是编写一个实现这两个函数的类,如下所示:
class My_file :
def __init__ (self, fname):
self.fname = fname
def __enter__ (self):
self.file = open(self.fname, \'w\' )
return self.file
def __exit__ (self, exc_type, exc_val, exc_trace_back):
if self.file:
self.file.close()
在这里,我们创建了一个普通的 Python 类,实现了两个魔术函数。注意这两个函数的签名: __enter__ 只接受 self ,而 __exit__ 将接受更多参数,示例中的这三个是标准形式。这样,我们就可以直接使用:
with My_file( \'hello.txt\' ) as f:
f.write( \'hello, world!\' )
这里的 with 语句会先调用 __init__ 构造一个新对象,然后再调用 __enter__ 方法;最后,它会在代码块完成之前触发 __exit__ 方法。所以,上面代码的大致等价如下:
myfile = My_file( \'hello.txt\' )
f = myfile.__enter__()
f.write( \'hello, world!\' )
myfile.__exit(...)
实现 上下文管理器 的第二种方法是通过 装饰器 ,如下:
1.你 import contextmanager from contextlib
2.你写一个函数来实现你想要的 with 语句。
3.在函数上方添加一个装饰器 @contextmanager 。
4.使用你的 with your_function !
根据上面的介绍,让我们写一个 装饰器上下文管理器 !
from contextlib import contextmanager
@contextmanager
def my_file_open (fname):
try :
f = open(fname, \'w\' )
yield f
finally :
print( \'Closing file\' )
f.close()
with file_open( \'hi.txt\' ) as f:
f.write( \'hello world\' )
@contextmanager
def closing (f):
try :
f.write( "Finish writing" )
finally :
f.close()
with closing(open( "hi.text" )):
f.write( "hello world" )
例如,在上面的代码中,我们可以直接调用 with close(your_way_of_getting_resource) ,在你下面写的代码块即将完成之前( f.write("hello world") ),它会执行 try..finally 我们在上面定义的块。另一个是使用 suppress 工具。我们知道,在很多情况下,如果我们尝试获取一些资源,很可能在打开文件时会出现 FileNotFoundException 等错误。在某些情况下,我们希望捕获错误或抑制错误,以便程序继续正常运行。 suppress 是我们可以抑制警告的一种方式。你需要做的就是弄清楚你想要抑制哪个异常,并编写 with suppress(your_choice_of_exception) ,Python 将从这里开始处理它。在其他情况下,您可能只想在输入 with 代码块时执行某些操作。在这种情况下, nullcontext 对你来说会很方便。 nullcontext 只会返回你在 __enter__ 函数中定义的东西,而不会做任何其他事情。如果您在 Python 中处理 async 操作以访问资源,则 aclosure 是处理这种情况的实用工具。
总结
本文介绍了 with 语句的一些基本概念和用法及其底层工作原理。还有很多有趣的东西,请查看 Python 的 contextlib 文档。最后,祝您能像往常一样快乐学习和快乐编码!
链接:https://python.plainenglish.io/demystifying-the-with-keyword-in-python-53be94e8b31a
你还有什么想要补充的吗?
python的with关键字
参考技术A with表达式其实是try-finally的简写形式。但是又不是全相同。其中的context是一个表达式,返回的是一个对象,var用来保存context表达式返回的对象,可以有单个或者多个返回值。
表达式open('1.txt')返回是一个_io.TextIOWrapper 类型的变量用f接受到。在with语句块中就可以使用这个变量操作文件。执行with这个结构之后。f会自动关闭。相当于自带了一个finally。
但是with本身并没有异常捕获的功能,但是如果发生了运行时异常,它照样可以关闭文件释放资源。
这个例子可以看出with没有捕获异常的功能。
这个例子可以看出with发生了异常也会关闭程序。
自定义类必须包含上述几个方法才能正确使用with关键字。
下面我们故意加一个NameError
即使程序发生了错误,python解释器终止了我们的程序,但是我们的类 还是顺利关闭了。
1、文件操作。2、进程线程之间互斥对象。3、支持上下文其他对象
以上是关于揭秘 Python 中的 with 关键字的主要内容,如果未能解决你的问题,请参考以下文章