Python 和 Java 异常处理对比

来源:互联网 发布:网络推广营销培训 编辑:程序博客网 时间:2024/05/31 06:22

当你在编写程序时,可能由于人为或其它因素导致发生异常后,如果不对异常处理,程序就无法继续执行。Python语言中也有自己的异常处理,下面我们先看下Java中的异常处理,然后再对比Python中的异常处理,其实它们都大同小异。java 中的异常处理我们不做过多介绍,只是为了和python的异常处理做对比,加深理解。

一、.Java 中的异常处理

java 中 处理异常有五个关键字:try catch finally throw throws
try:将可能发生的异常存放到try块中
catch:对异常进行捕获
finally:无论是否出现异常都执行
throw:在方法体中抛出异常
throws:在方法上抛出异常

java 中对异常的处理更加严谨,异常的种类及结构如下

这里写图片描述

java 中 所有异常的父类为Throwable,Throwable 中有两个重要的子类:Error(错误)和 Exception(异常)

Error 是不可恢复的异常,比如:JVM 溢出。
Exception 又分为两种异常:检查时异常和运行时异常。
检查时异常的特点是需要客户程序员捕获异常(try)或抛出异常(throws)让调用着来处理,比如在IO编程、线程、xml解析应用中的异常都为检查时异常,需要我们手动捕获或抛出异常。

// 检查时异常public static  void main(String[] args){    try {        System.in.read();    } catch (IOException e) {        e.printStackTrace();    }}

运行时异常指的是所有的RuntimeException及其子类,特点是无须客户程序员try或throws

// 运行时异常public static void main(String[] args){    args[1] = "exception"; // 数组下标访问越界}

在实际编程中,有时我们会自己定义一些异常来对异常进行处理,java 中 自定义检查时异常需要继承Exception 类并覆盖方法,自定义运行时异常需要继承 RuntimeException 并覆盖方法。

// 自定义检查时异常public class MyException extends Exception {    public MyException() {        super();    }    public MyException(String message) {        super(message);    }    public MyException(String message, Throwable cause) {        super(message, cause);    }    public MyException(Throwable cause) {        super(cause);    }    protected MyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {        super(message, cause, enableSuppression, writableStackTrace);    }    // 测试(需要捕获或抛出异常)    public static  void main(String[] args){        try {            throw new MyException("自定义检查时异常");        } catch (MyException e) {            e.printStackTrace();        }    }}
// 自定义运行时异常public class MyRuntimeException extends  RuntimeException {    public MyRuntimeException() {        super();    }    public MyRuntimeException(String message) {        super(message);    }    public MyRuntimeException(String message, Throwable cause) {        super(message, cause);    }    public MyRuntimeException(Throwable cause) {        super(cause);    }    protected MyRuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {        super(message, cause, enableSuppression, writableStackTrace);    }    // 测试(不需要捕获或抛出异常)    public static  void main(String[] args){        throw new MyRuntimeException("自定义运行时异常");    }}

二、Python 中的异常处理

python 中的异常处理相比java来说,要简单一些,python 中使用四个关键字来处理异常
try:捕获异常,类似于 java 中的 try
except:处理异常,类似于 java 中的 catch
finally:不管是否捕获到异常都会被执行,类似于 java 中 的 finally
raise:抛出异常,类似于 java 中的 throw

异常执行流程:
      try块存放可能出现的异常代码,如果没有异常发生,忽略except子句,try子句执行后结束;如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略,如果异常的类型和 except 之后的名称相符,那么对应的except子句将被执行。最后执行 try 语句之后的代码。不管try在执行时,是否发生了异常,finally块中的内容都会被执行。

python是一种解释型语言,也就是说没有编译,所有它没有检查时异常,只有运行时异常,python 中常见异常如下

异常 描述 AssertionError assert(断言)语句失败 AttributeError 访问一个对象没有的属性,比如foo.x ,foo没有x这个属性。 IOError 输入/输出异常,基本上是无法打开文件 ImportError 无法引入模块或者包,基本上是路径问题 IndentationError 语法错误,代码没有正确对齐 IndexError 下标访问越界,比如当x只有三个元素,却试图访问x[5] KeyError 试图访问字典里不存在的键 KerboardInterrupt Ctrl + C 被按下 NameError 使用一个还未被赋值予对象的变量 SyntaxError Python代码非法,代码不能解释 TypeError 传入对象类型与要求的不符 UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另一个同名的全局变量,导致你以为正在访问它 ValueError 传入一个调用者不期望的值,即使值的类型是正确的



python 中经常用 print() 来打印输出内容,使用print()抛出异常,示例如下

print(5/0)

这里写图片描述

1.raise 抛出异常

示例:输入一个数字,如果不是数字则抛出异常ValueError

inputValue=input("请输入一个数字:")type(inputValue)if inputValue.isdigit():    print(inputValue)else:    raise ValueError

运行结果1:
请输入一个数字:1
1

运行结果2:
请输入一个数字:hello
Traceback (most recent call last):
File “C:\Users\Administrator\Desktop\test.py”, line 6, in
raise ValueError
ValueError

2.try…except…

我们在编写程序时,可能会出现一些错误或异常,如果不进行处理那么程序就会中止执行,示例如下,访问字符串中下标为20的字符时,会抛出IndexError异常

str = "hello python"print(str[20])  # IndexError: string index out of range

运行结果:
Traceback (most recent call last):
File “E:/code/workspace_python/class/python_day03/testError.py”, line 2, in
print(str[20]) # IndexError: string index out of range
IndexError: string index out of range

改写示例,使用 try…except… 处理异常

str = "hello python"try:    print(str[20])except IndexError:    print('error...')

再次运行程序,发生异常后会打印 error…

3.try….except…else

str = "hello python"try:    print(str[10])except IndexError:    print('error...')else:    print('no error...')

运行结果:
o
no error…

将 str[10] 该为str[20],else块中的内容将不会执行,运行结果为:error…

4.try…except…finally

我们通过一个小案例来看下 try…except…finally 是如何处理异常的,输入两个数字然后做除法运算,将可能发生的异常代码放到 try 块中,except 块中对捕获到的异常继续处理

try:    num1 = int(input("请输入第一个数:"))    num2 = int(input("请输入第二个数:"))    result = num1 / num2    print("{0} / {1} = num{2}".format(num1, num2, result))except ValueError as e:    print("ValueError:{0}".format(e))finally:    print("bye bye");

运行结果1:
请输入第一个数:10
请输入第二个数:5
10 / 5 = num2.0
bye bye

运行结果2:第二个数字为字符h,抛出异常ValueError
请输入第一个数:1
请输入第二个数:h
ValueError:invalid literal for int() with base 10: ‘h’
bye bye

运行结果3:除数为0,抛出异常ZeroDivisionError
请输入第一个数:1
请输入第二个数:0
Traceback (most recent call last):
File “E:/code/workspace_python/class/python_day03/testError.py”, line 4, in
result = num1 / num2
ZeroDivisionError: division by zero

bye bye

运行结果3中抛出了一个ZeroDivisionError异常,我们并没有对这个异常做处理,异常处理时可以有多个except子句,修改上述代码

try:    num1 = int(input("请输入第一个数:"))    num2 = int(input("请输入第二个数:"))    result = num1 / num2    print("{0} / {1} = num{2}".format(num1, num2, result))except ValueError as e:    print("ValueError:{0}".format(e))except ZeroDivisionError as e:    print("ZeroDivisionError:{0}".format(e))finally:    print("bye bye");

运行结果:
请输入第一个数:1
请输入第二个数:0
ZeroDivisionError:division by zero
bye bye

一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行,当有多个except子句时,可以将异常写在一个元祖里,改写上述代码

try:    num1 = int(input("请输入第一个数:"))    num2 = int(input("请输入第二个数:"))    result = num1 / num2    print("{0} / {1} = num{2}".format(num1, num2, result))except (ValueError, ZeroDivisionError)as e:    print("Error:{0}".format(e))finally:    print("bye bye");

运行结果同上

5.传递异常

异常处理时,有时候我们在函数或方法内捕获到了异常,但是又想重新引发它(传递异常),可以使用不带参数的raise语句实现,代码如下

class Mcl:    def calc(self, num1, num2):        try:            result = num1 / num2            print("{0} / {1} = {2}".format(num1, num2, result))            return num1 / num2        # 捕获到异常后不做处理        except ZeroDivisionError as e:            raise
app = Mcl()app.calc(10, 2)# 运行结果# 10 / 2 = 5.0
app = Mcl()app.calc(1, 0)# 运行结果(抛出异常):ZeroDivisionError: division by zero

6.自定义异常

class MyError(Exception):    # 覆盖Exception的__init__()方法    def __init__(self, value):        self.value = value    def __str__(self):        return repr(self.value)raise MyError("自定义异常!")

运行结果
Traceback (most recent call last):
File “E:/code/workspace_python/class/python_day03/testError.py”, line 7, in
raise MyError(“自定义异常!”)
main.MyError: ‘自定义异常!’

原创粉丝点击