Python|捕获和创建异常
捕获所有异常有时会被那些无法记住复杂操作中可能发生的所有异常的程序员用作拐杖。因此,这也是编写不可调试代码的好方法。
因此,如果捕获所有异常,那么在某处记录或报告异常的实际原因(例如,日志文件、打印到屏幕的错误消息等)是绝对关键的。
问题——捕获所有异常的代码
代码 #1:为 Exception 编写一个异常处理程序以捕获所有异常。
try:
...
except Exception as e:
...
# Important
log('Reason:', e)
这将捕获除SystemExit
、 KeyboardInterrupt
和GeneratorExit
之外的所有异常。
代码#2:考虑这个例子。
def parse_int(s):
try:
n = int(v)
except Exception:
print("Couldn't parse")
代码#3:使用上述函数
print (parse_int('n / a'), "\n")
print (parse_int('42'))
输出 :
Couldn't parse
Couldn't parse
在这一点上,问题出现了它是如何不起作用的。现在如果函数被写成:
代码#4:
def parse_int(s):
try:
n = int(v)
except Exception as e:
print("Couldn't parse")
print('Reason:', e)
在这种情况下,将收到以下输出,这表明发生了编程错误。
parse_int('42')
输出 :
Couldn't parse
Reason: global name 'v' is not defined
问题 -用在应用程序上下文中具有更多意义的自定义异常包装较低级别的异常(正在处理)。
要创建新的异常,只需将它们定义为从Exception继承的类(或其他现有异常类型之一,如果它更有意义的话)。
代码 #5:定义一些自定义异常
class NetworkError(Exception):
pass
class HostnameError(NetworkError):
pass
class TimeoutError(NetworkError):
pass
class ProtocolError(NetworkError):
pass
代码#6:以正常方式使用这些异常。
try:
msg = s.recv()
except TimeoutError as e:
...
except ProtocolError as e:
...
- 自定义异常类几乎应该总是继承自内置的异常类,或者继承自一些本地定义的基异常,而基异常本身又继承自异常。
- BaseException 保留用于系统退出异常,例如 KeyboardInterrupt 或 SystemExit,以及其他应指示应用程序退出的异常。因此,捕获这些异常并不是预期的用例。