亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> Python

避开 Python 异常处理常见坑:正确捕获与处理异常

避开 Python 异常处理常见坑:正确捕获与处理异常

我见太多人异常处理用错。或许你也中招。以下场景耳熟吗?

写代码时知道调用库可能抛异常,但记不清具体哪个。此时极易用“捕获一切”块图省事继续写业务逻辑。

目录

最坏写法

最糟是裸 except: 捕获一切:

try:
    ...
except:
    pass

危害:
1. 完全不知还可能抛出何种异常。
2. 用 pass 静默吞掉异常,等于埋雷。
更甚者,裸 except 等同 except BaseException,连 KeyboardInterrupt (Ctrl+C)、SystemExit、NameError 全捕获!导致如下代码无法正常中断:

from time import sleep
while True:
    try:
        print("Try and stop me")
        sleep(1)
    except:
        print("Don't.. stop.. me now!")

亲测可行:只能关终端或 kill 进程才能停。

稍好但仍不推荐的全捕获

用 except Exception 虽仍属偷懒大网捕鱼,但至少能正常响应中断信号:

from time import sleep
while True:
    try:
        print("Try and stop me")
        sleep(1)
    except Exception:
        print("Ok I'll stop!")

为何?所有异常继承自 BaseException。文档规定:except 子句指定类时,自动捕获其子类。裸 except 即 except BaseException,故全捕获。
而 Exception 类定义为:“所有内置非系统退出异常均派生自此。用户自定义异常亦应派生自此。”故 KeyboardInterrupt 等系统级异常不在其列。

更坑人的情况

调用 os.getcwd() 手滑写成 os.getcdw():

import os
try:
    working_dir = os.getcdw()
    print(working_dir)
except:
    print('error')

因 os.getcdw 不存在,抛 NameError。裸 except 捕获并打印 'error',程序继续跑,拼写错误隐匿不发。改用 except Exception 也救不了——NameError 继承自 BaseException 而非 Exception!
第一招并非万能药。那该怎么办?

只捕获你能处理的

异常处理金句:catch what you can handle。开发者常想就地处理异常,但往往应让异常冒泡至真正能处理的层级。

例:文本编辑器打开加载文件的 OpenFile 类。用户请求打开不存在文件,可就地处理,也可向上抛。
此处向上抛更妥:OpenFile 无法判断异常对调用者严重程度。调用者可多策应对:
• 新建同名文件继续
• 因必须有文件而弹错告知用户
决策权不在 OpenFile。

异常是否必须全抛?否。OpenFile 可自处理 TimeoutError:重试几次不打扰调用者。这是它能处理的异常,捕获重试合理。

结论

绝不捕获超出处理能力的异常。裸 except 是 Bug 温床与不可预测代码根源。铭记:只捕获你能处理的。
按此信条写代码,裸 except 即破坏规则。请停止滥用。练习:回顾旧代码,用新认知重构改进!

Python

  1. 精通 CMMS 培训:激活团队与强化留存的实战框架
  2. 招聘季来袭:后疫情时代应对申请人激增的四大策略
  3. 精通Python运算符:全面指南
  4. 精通 Python 错误与内置异常
  5. 精通 Python 自定义异常:实战指南
  6. Python 获取当前日期和时间:实用指南
  7. Python print() 函数完全指南:基础用法、空行打印与自定义结束符
  8. Python 字典增删改查与嵌套操作实战指南
  9. Python print 不换行:掌握 end 参数及其他技巧
  10. Python 计算平均值:从循环到 NumPy 的四种实战方法
  11. Python 异常处理全攻略:从入门到精通
  12. 精通 Java 多异常捕获:单 catch 块处理多异常