1. 为什么要使用with…as语句?

当我们用Python的open()函数打开一个文件时,就像是打开了一扇门,可以进入文件的世界,尽情地操作它。而当我们完成操作后,就像是离开了那个文件的世界,我们需要关上那扇门,以免文件中的内容泄露或者被其他人偷窥。

所以,我们需要调用close()函数来关闭文件,就像是轻轻地关上那扇门,让文件恢复到安全的状态。这样,我们就可以放心地离开,不用担心文件会被损坏或者丢失。

记住,打开文件就像是进入了一个神奇的世界,而关闭文件就像是离开了那个世界,回到了现实生活中。所以,在使用open()函数打开文件时,一定要记得在操作完后调用close()函数关闭文件,就像是在离开一个房间前关上门一样。这样,我们就能保证文件的安全,同时也能养成良好的编程习惯。

f = open(路径, 'r')
f.close()

如果文件不存在,就会抛出一个IOError的错误,后面的close()将不会执行。这就像是你去餐厅点了一道美味的菜,但是厨师告诉你他们没有这道菜的原料,所以你无法享受到这道美食。为了保证无论是否出错都可以正确关闭文件,我们可以使用try…finally结构实现,就像是你去餐厅吃饭,无论你点了什么菜,最后都会有服务员来为你收拾桌子,让你离开餐厅的时候心满意足。这样,我们就能够优雅地处理文件操作中的异常情况,同时确保资源的正确释放。

try:
    f = open(路径, 'r')
finally:
    f.close()

写代码就像是在和一只顽皮的小猴子打交道,你永远不知道它会在哪里捣蛋。所以,我们需要使用 tryexcept 来捕捉可能抛出的异常。但是,有时候我们会遇到一些特殊情况,比如打开了一个文件,但是在处理过程中发生了异常,导致文件没有被关闭。这就像是你在读书的时候,突然有人闯进来,你被吓得扔下书就跑,结果书没关上。这时候,finally 就像是一个可靠的朋友,它会在任何情况下都会来帮你关上书,即使有人闯进来,你也不用担心书会被弄丢。

所以,为了保证文件能够被正确关闭,我们需要在 finally 块中编写关闭文件的代码。这样,无论程序是否抛出异常,我们都可以确保文件被关闭,避免资源的浪费和潜在的问题。

记住,finally 是一个可靠的朋友,它会在你最需要的时候出现,帮你解决问题。所以,不要忘记在处理文件时使用 finally,让它来帮你关上那些被吓得扔下的书!

2. with语句是什么

在Python的世界里,有一位自动化大师,他名叫with…as语句,也被亲切地称为上下文管理器。这位大师的任务就是帮助我们自动分配并释放资源,就像一个贴心的管家一样。

想象一下,你是一位忙碌的程序员,每天都要和文件、数据库等打交道。但是,你总是会忘记手动关闭它们,就像忘记关灯一样。这时,with…as语句就像是一位机智的管家,他会在你使用完资源后,自动帮你关闭它们,就像是一种自动释放的魔法。

使用with…as语句就像是和这位管家签订了一份合同,他会在你的代码块执行完毕后,自动帮你清理战场,释放资源。这样,你就可以省心地专注于你的代码逻辑,而不用担心资源的释放问题。

所以,记住,当你需要操作文件、数据库等资源时,不要忘记召唤这位自动化大师,使用with…as语句,让他帮你自动化地完成清理工作。这样,你就能轻松愉快地编写Python代码,而不用担心资源泄露的麻烦。

with…as 语句的语法格式如下

with 表达式 as 变量名:
	代码块
	代码块

其中 as 变量名可以省略,如果使用表示将前文表达式的结果保存到一个变量中。

3. with语句的作用

with语句就像是一位贴心的管家,能够自动帮你管理上下文资源。无论你是因为什么原因跳出了with块,它总能确保文件得到正确的关闭,就像是一位细心的管家帮你关上门一样。这样一来,你就不需要亲自动手写close()来关闭文件了,资源的释放就像是自动魔法一样。简直就像是有一位隐形的管家在背后默默地为你服务,释放你的资源。

常规操作文件代码

# 1. 打开 - 文件名需要注意大小写
file = open("README.txt")

# 2. 读取
text = file.read()
print(text)

# 3. 关闭
file.close()
  • 注意:必须得有file.close()关闭文件

with语法的代码

with open("README.txt") as f:   
    data= f.read()
    print(data)
  • 可以看出 with语句 更加简洁方便,也不用担心没写关闭造成资源浪费

4. with语句工作原理

定义原则:是with所求值的对象必须有一个__enter__()方法,一个__exit__()方法。

执行步骤

  • 1.紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。

  • 2.当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。

定义一个类具体说明with工作如何工作

  • 实现了特殊方法__enter__(),__exit()称为该类对象遵守了上下文管理器协议

  • 该类对象的实例对象,称为上下文管理器

class MyContentMgr(object):
    def __enter__(self):
        print("enter方法被调用执行了")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("exit方法被调用执行了")

    def show(self):
        print("show方法被调用执行了")


with MyContentMgr() as file:
    file.show()

运行代码,输出结果如下:

enter方法被调用执行了
show方法被调用执行了
exit方法被调用执行了
  • 可以发现在show方法结束后自动调用了对象的__exit__()方法。

5. with语句自动处理异常

with真正强大之处是它可以处理异常。就像一位超级英雄,它能够在代码中捕捉异常并及时处理。我们来看看一个例子,以更好地理解它的工作原理。

假设我们有一个名为MyContentMgr的类,它具有一个__exit__方法,该方法接受三个参数:exc_type, exc_val, exc_tb。这些参数在异常处理中相当有用,就像一把锁匙,可以打开异常的大门。

现在,让我们做一个小小的改动,让代码变得更加生动有趣。我们将使用一个比喻来描述这个过程。

想象一下,你是一名勇敢的探险家,正在探索一个神秘的洞穴。你手里拿着一把神奇的钥匙,这把钥匙就是with关键字。当你进入洞穴时,你会遇到各种各样的陷阱和困难,就像代码中的异常一样。

但是,你不必担心!因为你有这把神奇的钥匙,它可以帮助你解决问题。当你遇到一个陷阱时,钥匙会自动打开,并告诉你发生了什么异常。你可以根据这些信息来采取适当的行动,比如修复问题或者继续前进。

所以,with关键字就像你的忠实伙伴,它会在你最需要的时候帮助你解决问题。它是你在代码世界中的超级英雄,保护你免受异常的困扰。

希望这个比喻能够帮助你更好地理解with关键字的强大之处!让我们一起继续探索代码的奇妙世界吧!

修改代码使show方法报错

class MyContentMgr(object):
    def __enter__(self):
        print("enter方法被调用执行了")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("exit方法被调用执行了")

    def show(self):
        print("show方法被调用执行了", 1 / 0)  # 这加上一个报错操作


with MyContentMgr() as file:
    file.show()

运行代码,输出结果如下:

enter方法被调用执行了
exit方法被调用执行了
Traceback (most recent call last):
  File "E:/Python_demo/1.py", line 14, in <module>
    file.show()
  File "E:/Python_demo/1.py", line 10, in show
    print("show方法被调用执行了", 1 / 0)  # 这加上一个报错操作
ZeroDivisionError: division by zero
  • 可以看出即使show方法报错依然不影响__exit__方法自动调用

因此,Python的with语句就像是一位贴心的管家,为我们提供了一个方便的机制,让我们的代码更加简洁,同时在异常出现时,也能够轻松地处理清理工作。

想象一下,你正在做一道复杂的烹饪菜谱,而with语句就像是一把神奇的魔法锅。当你需要使用某个材料时,只需将其放入魔法锅中,然后开始烹饪。而当你完成了烹饪,或者出现了意外情况时,魔法锅会自动帮你处理掉剩余的材料,让你无需操心清理工作。

这就好比是在一场冒险中,你带着一位忠实的伙伴,一同探索未知的领域。当你们遇到困难或者危险时,伙伴会立即出现,帮助你们解决问题,保护你们的安全。而当冒险结束时,伙伴会默默地离开,不留任何痕迹。

所以,使用with语句就像是拥有了一位贴心的管家或者忠实的冒险伙伴,让我们的代码更加优雅,同时也能够轻松应对异常情况和清理工作。让我们感受一下这种便利吧!