编程学习网 > 编程语言 > Python > Python 上下文管理器和 else 块!
2025
07-05

Python 上下文管理器和 else 块!

先做这个,再做那个:if语句之外的else块

这个语言特性不是什么秘密,但却没有得到重视:else 子句不仅能在 if 语句中使用,还能在 for、while 和 try 语句中使用。

for/else、while/else 和 try/else 的语义关系紧密,不过与 if/else 差别很大。起初,else 这个单词的意思阻碍了我对这些特性 的理解,但是最终我习惯了。

else 子句的行为如下。

for

仅当 for 循环运行完毕时(即 for 循环没有被 break 语句中止) 才运行 else 块。

while
 仅当 while 循环因为条件为假值而退出时(即 while 循环没有被 break 语句中止)才运行 else 块。

try仅当 try 块中没有异常抛出时才运行 else 块。官方文档 (https://docs.python.org/3/reference/compound_stmts.html)还指 出:“else 子句抛出的异常不会由前面的 except 子句处理。”

在所有情况下,如果异常或者 return、break 或 continue 语句导致 控制权跳到了复合语句的主块之外,else 子句也会被跳过。

我觉得除了 if 语句之外,其他语句选择使用 else 关键字是 个错误。else 蕴含着“排他性”这层意思,例如“要么运行这个循 环,要么做那件事”。可是,在循环中,else 的语义恰好相反:“运行这个循环,然后做那件事。”因此,使用 then 关键字更 好。then 在 try 语句的上下文中也说得通:“尝试运行这个,然后 做那件事。”可是,添加新关键字属于语言的重大变化,而 Guido 唯恐避之不及。

在这些语句中使用 else 子句通常能让代码更易于阅读,而且能省去一 些麻烦,不用设置控制标志或者添加额外的 if 语句。

在循环中使用 else 子句的方式如下述代码片段所示:


一开始,你可能觉得没必要在 try/except 块中使用 else 子句。毕 竟,在下述代码片段中,只有 dangerous_call() 不抛出异 常,after_call() 才会执行,对吧?


然而,after_call() 不应该放在 try 块中。为了清晰和准确,try 块 中应该只抛出预期异常的语句。因此,像下面这样写更好:



不是 after_call()。而且很明显,只有 try 块不抛出异常,才会执行 after_call()。

在 Python 中,try/except 不仅用于处理错误,还常用于控制流程。为 此,Python 官方词汇表(https://docs.python.org/3/glossary.html#termeafp) 还定义了一个缩略词(口号)。

EAFP
取得原谅比获得许可容易(easier to ask for forgiveness than permission)。这是一种常见的 Python 编程风格,先假定存在有效 的键或属性,如果假定不成立,那么捕获异常。这种风格简单明 快,特点是代码中有很多 try 和 except 语句。与其他很多语言一 样(如 C 语言),这种风格的对立面是 LBYL 风格。

接下来,词汇表定义了 LBYL。

LBYL

三思而后行(look before you leap)。这种编程风格在调用函数 或查找属性或键之前显式测试前提条件。与 EAFP 风格相反,这种 风格的特点是代码中有很多 if 语句。在多线程环境中,LBYL 风 格可能会在“检查”和“行事”的空当引入条件竞争。例如,对 if key in mapping: return mapping[key] 这段代码来说,如果 在测试之后,但在查找之前,另一个线程从映射中删除了那个键, 那么这段代码就会失败。这个问题可以使用锁或者 EAFP 风格解 决。

如果选择使用 EAFP 风格,那就要更深入地了解 else 子句,并在 try/except 语句中合理使用。

以上就是“导师:我求求你,Python的环境设置你自己学好不好?的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。

扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取