知行编程网知行编程网  2022-11-08 12:00 知行编程网 隐藏边栏  1 
文章评分 0 次,平均分 0.0
导语: 本文主要介绍了关于Python中怎么使用with语句?的相关知识,希望可以帮到处于编程学习途中的小伙伴

有些任务可能需要事先设置并在之后清理。对于这种情况,Python 的 with 语句提供了一种非常方便的处理方式。一个很好的例子是文件处理,你需要获取一个文件句柄,从文件中读取数据,然后关闭文件句柄。

如何在 Python 中使用 with 语句?

如果不用with语句,代码如下:

代码如下:

file = open("/tmp/foo.txt")
data = file.read()
file.close()

这里有两个问题。一是你可能忘记关闭文件句柄;另一种是文件读取数据异常,没有进行处理。这是处理异常的增强版本:

代码如下:

file = open("/tmp/foo.txt")
try:
data = file.read()
finally:
file.close()

虽然这段代码工作正常,但它太冗长了。现在是尝试的时候了。 with 除了拥有更优雅的语法外,还可以处理上下文产生的异常。这是 with 版本的代码:

代码如下:

with open("/tmp /foo.txt") as file:
data = file.read()


with如何工作?

它看起来像魔术,但它不仅仅是魔术,Python 对 with 的处理很聪明。基本思想是 with 求值的对象必须有一个 __enter__() 方法和一个 __exit__() 方法。

with 后面的语句被求值后,调用返回对象的 __enter__() 方法,该方法的返回值将赋给 as 后面的变量。当 with 后面的代码块全部执行完毕后,会调用之前返回对象的 __exit__() 方法。

下面例子可以具体说明with如何工作:

代码如下:

#!/usr/bin/env python
# with_example01.py
class Sample:
def __enter__(self):
print "In __enter__()"
return "Foo"
def __exit__(self, type, value, trace):
print "In __exit__()"
def get_sample():
return Sample()
with get_sample() as sample:
print "sample:", sample

代码如下:

bash-3.2$ ./with_example01.py
In __enter__()
sample: Foo
In __exit__()

正如你看到的,

__enter__()方法被执行

__enter__()方法返回的值 - 这个例子中是"Foo",赋值给变量'sample'

执行代码块,打印变量"sample"的值为 "Foo"

__exit__()方法被调用

with 的真正强大之处在于它可以处理异常。你可能已经注意到 Sample 类的 __exit__ 方法具有三个参数 - val、type 和 trace。这些参数在异常处理中非常有用。让我们更改代码,看看它是如何工作的。

代码如下:

#!/usr/bin/env python
# with_example02.py
class Sample:
def __enter__(self):
return self
def __exit__(self, type, value, trace):
print "type:", type
print "value:", value
print "trace:", trace
def do_something(self):
bar = 1/0
return bar + 10
with Sample() as sample:
sample.do_something()

在本例中,with 后的 get_sample() 变为 Sample()。没关系,只要 with 后面的语句返回的对象有 __enter__() 和 __exit__() 方法。在本例中,Sample() 的 __enter__() 方法返回新创建的 Sample 对象并将其分配给变量 sample。

代码如下:

bash-3.2$ ./with_example02.py
type: 
value: integer division or modulo by zero
trace: 
Traceback (most recent call last):
File "./with_example02.py", line 19, in 
sample.do_somet hing()
File "./with_example02.py", line 15, in do_something
bar = 1/0
ZeroDivisionError: integer division or modulo by zero

事实上,__exit__() 方法是在 with 后面的代码块抛出任何异常时执行的。如示例所示,当抛出异常时,关联的类型、值和堆栈跟踪将传递给 __exit__() 方法,因此会打印抛出的 ZeroDivisionError 异常。在开发库时,可以将清理资源、关闭文件等操作放在 __exit__ 方法中。

因此,Python 的 with 语句是一种有效的机制,可以让代码更加简洁,同时在发生异常时,清理工作也更加轻松。

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写
扫一扫二维码分享