Python - if 语句之外得 else 块
这个语言功能不是什么秘密,只不过没有得到重视:else 子句不仅能在if 语句中使用,还可以在for、while 和 try 语句中使用。
for/else、while/else 和 try/else 的语义联系紧密,不过与if/else 差别很大。
else 子句的规则如下:
-
for : 仅当for 循环运行完毕时(即 for 循环没有被break 语句中止) 才运行else 块
-
while: 仅当while 循环没有 被 break 语句中止 才运行 else 块
-
try: 仅当try 块没有抛出异常时才运行else 块。官方文档还指出:"else 子句抛出的异常不由前面的expect 子句处理"
在所有情况下,如果异常或者 return、break 或continue 语句导致控制权跳到了 符合语句的主块之外,则else 子句也被跳过。
在这些语句中使用else 子句通常能让代码更易于阅读,而且能省去一些麻烦,不用设置控制标志或者添加额外的if 语句。
如下案例:
list = [1, 2, 3]
flag = False
for item in list:
if item == 4:
flag = True
break
if flag:
print('找到相关数据')
else:
print(f'未找到相关逻辑')
完全等价于:
list = [1, 2, 3]
for item in list:
if item == 4:
break
else:
print('未找到相关数据')
# 执行未找到逻辑
一开始,你可能会觉得没必要再 try/expect 块中使用else 子句。毕竟,在下述代码片段中,只用dangerous_call() 不抛出异常,after_call() 才会执行,对吧?
try:
dangerous_call()
after_call()
except OSError:
log('OSError')
然而,after_call() 不应该放在try 块中。为了清晰和准确,只应该把可能抛出预期异常的语句放在try 块中。因此,像下面这样写更好。
try:
dangerous_call()
except OSError:
log('OSError')
else:
after_call()
现在很明确,try 块防守的是 dangerous_call() 可能会出现的错误,而不是after_call() 。而且很明显,只有try 块不抛出异常,after_call() 才会执行。
在Python 中,try/except 不仅用于处理错误,还常用于控制流程。为此,Python 官方属于还定义了一个缩略词(口号)
- EAFP
取得原谅比获得许可容易(Easier to ask for forgiveness then permission)。这是一种常用的Python 编程风格,先假定存在有效的键或属性,如果假设不成立,那么捕获异常,这种风格简单明快,特点是 代码中有很多 try 和 except 语句。与其他很多语言一样(例如C语言),这种风格的对立面是LBYL 风格。
接下来,Python 术语表定义了LBYL。
- LBYL
三思而后行(Look befor you leap)。这种编程风格在调用函数或查找属性或键之前显式测试前提条件。与EAFP风格相比,这种风格的特点是代码中有很多if 语句,在多线程环境中,LBYL风格可能会在"检查" 个 "行事" 的 空隙引入条件竞争。例如,对
if key in mapping: return mapping[key] 这段代码来说,如果在测试之后————但在查找之前————另一个线程从映射中删除了那个键,那么这段代码就会失败。这个问题可以使用锁或者EAFP 风格解决
本文来自博客园,作者:chuangzhou,转载请注明原文链接:https://www.cnblogs.com/czzz/p/18249100
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2022-06-15 Jmeter - 使用问题记录