本文目录一览:
揭秘 Python 中的 with 关键字
正文
你有没有想过 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(...)
实现上下文管理器的第二种方法是通过装饰器,如下:
- 你
import contextmanager
fromcontextlib
- 你写一个函数来实现你想要的
with
语句。 - 在函数上方添加一个装饰器
@contextmanager
。 - 使用你的
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
文档。最后,祝您能像往常一样快乐学习和快乐编码!
链接:
你还有什么想要补充的吗?
python with函数怎么用
with
在 Python 中并不是函数,是一个关键词语句,比如 if
就是关键词语句。
with
大多用来打开一个文档。
比如:
with open('test.txt') as f:
f.read()
这样就可以读取名为 test
的文档里的内容,并且使用 with
语句不需要我们手动再调用文件的 close()
方法来关闭文件,如果 test.txt
文档对象不再被使用,with
会自动关闭文档。比较智能一点。
如何用python 中with 用法
要使用 with
语句,首先要明白上下文管理器这一概念。有了上下文管理器,with
语句才能工作。
下面是一组与上下文管理器和 with
语句有关的概念。
上下文管理协议(Context Management Protocol):包含方法 __enter__()
和 __exit__()
,支持该协议的对象要实现这两个方法。
上下文管理器(Context Manager):支持上下文管理协议的对象,这种对象实现了 __enter__()
和 __exit__()
方法。上下文管理器定义执行 with
语句时要建立的运行时上下文,负责执行 with
语句块上下文中的进入与退出操作。通常使用 with
语句调用上下文管理器,也可以通过直接调用其方法来使用。
运行时上下文(runtime context):由上下文管理器创建,通过上下文管理器的 __enter__()
和 __exit__()
方法实现,__enter__()
方法在语句体执行之前进入运行时上下文,__exit__()
在语句体执行完后从运行时上下文退出。with
语句支持运行时上下文这一概念。
上下文表达式(Context Expression):with
语句中跟在关键字 with
之后的表达式,该表达式要返回一个上下文管理器对象。
python的with语句如何使用?求详解!
其实你可以这样理解 with
,就是可以自动维护一下上下文,并自动回收资源。
这是不使用 with
的实现:
file = open("/tmp/foo.txt")
try:
data = file.read()
finally:
file.close()
这是使用 with
的实现:
with open("/tmp/foo.txt") as file:
data = file.read()
python的with关键字
with
表达式其实是 try-finally
的简写形式。但是又不是全相同。
其中的 context
是一个表达式,返回的是一个对象,var
用来保存 context
表达式返回的对象,可以有单个或者多个返回值。
表达式 open('1.txt')
返回是一个 _io.TextIOWrapper
类型的变量用 f
接收到。在 with
语句块中就可以使用这个变量操作文件。执行 with
这个结构之后。f
会自动关闭。相当于自带了一个 finally
。
但是 with
本身并没有异常捕获的功能,但是如果发生了运行时异常,它照样可以关闭文件释放资源。
这个例子可以看出 with
没有捕获异常的功能。
这个例子可以看出 with
发生了异常也会关闭程序。
自定义类必须包含上述几个方法才能正确使用 with
关键字。
下面我们故意加一个 NameError
。
即使程序发生了错误,Python 解释器终止了我们的程序,但是我们的类还是顺利关闭了。
- 文件操作。
- 进程线程之间互斥对象。
- 支持上下文其他对象。