python 面向对象编程

1.常见异常

1.1 什么是异常

print(a)

---------------------------------------------------------------------------

NameError Traceback (most recent call last)

in ()
----> 1 print(a)

NameError: name 'a' is not defined

3 / 0

---------------------------------------------------------------------------

ZeroDivisionError Traceback (most recent call last)

in ()
----> 1 3 / 0

ZeroDivisionError: division by zero

print("中文括号")

File "", line 1
print("中文括号")
^
SyntaxError: invalid character in identifier

list(tuple)

---------------------------------------------------------------------------

TypeError Traceback (most recent call last)

in ()
----> 1 list(tuple)

TypeError: 'tuple' object is not callable

1.2 异常处理

1.2.1 捕获异常

捕获异常的语法如下:
try:
    <语句>  
except <名字>:
      <语句>  

def div(a, b):
    try:
        return a / b
    except ZeroDivisionError:
         print("异常,除数为0")   
div(3,1)

3.0

div(3,0)

异常,除数为0

1.2.2 抛出异常

Python使用raise语句抛出一个指定异常。我们可以使用类(Exception的子类)或实例参数调用raise语句引发异常。使用类时程序会自动创建实例。

raise Exception

---------------------------------------------------------------------------

Exception Traceback (most recent call last)

in ()
----> 1 raise Exception

Exception:

try:
    raise NameError("This is a NameError.")
except NameError:
    print("An exception happened!")  #只做了捕获

An exception happened!

try:
    raise NameError("This is a NameError.")
except NameError:   #捕获到异常
    print("An exception happened!")
    raise  # 抛出

An exception happened!

---------------------------------------------------------------------------

NameError Traceback (most recent call last)

in ()
1 try:
----> 2 raise NameError("This is a NameError.")
3 except NameError: #捕获到异常
4 print("An exception happened!")
5 raise # 抛出

NameError: This is a NameError.

Python中重要的内建异常类
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xHoCTci8-1584888726939)(attachment:image.png)]]( https://img-blog.csdnimg.cn/20200322225436739.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MjQ5Mzg4,size_16,color_FFFFFF,t_70)

1.2.3 捕获多个异常

def div(a, b):
    try:
        return a / b
        n = name
    except ZeroDivisionError:
         print("异常,除数为0") 
    except NameError:
         print("未声明初始化对象")
div(3, 0)

异常,除数为0

def div(a, b):
    try:
        n = name
        return a / b
      
    except ZeroDivisionError:
         print("异常,除数为0") 
    except NameError:
         print("未声明初始化对象")
div(3, 0)

未声明初始化对象

1.2.4 捕捉对象

def div(a, b):
    try:
        return a / b
        n = name
    except ZeroDivisionError as e:
         print(e) 
            
div(3, 0)

division by zero

1.2.5 全捕捉

def div(a, b):
    try:
        c = a / b
    except:
         print("Have Error.")  # 具体的异常未指出
    else:
        print("No Error.")
             
div(3, 0)

Have Error.

div(3, 1)

No Error.

1.2.5 自定义异常

class MyError(Exception):
    def __init__(self):
        pass 
    def __str__(self):
        return "该异常为自定义异常。"
    
def my_error_test():
    try:
        raise MyError()
    except MyError as e:
        print(e)

my_error_test()

该异常为自定义异常。

1.2.6 finally子句

  • 无论try子句中是否发生异常,finally都会被执行。
  • try、except、else和finally可以组合使用,但要记得else在except之后,finally在except和else之后。
def div(a, b):
    try:
        c = a / b
    except:
         print("Have Error.")  # 具体的异常未指出
    else:
        print("No Error.")
    finally:
        print("Program End.")     
div(3, 0)

Have Error.
Program End.

div(3, 1)

No Error.
Program End.

1.2.7 异常和函数

  异常和函数能够很自然地一起工作。如果异常在函数内引发而不被处理,就会传播至函数调用的地方。如果异常在函数调用的地方也没有被处理,就会继续传播,一直到达主程序。如果在主程序也没有做异常处理,异常就会被Python解释器捕获,输出一个错误信息,然后退出程序。

def div(a, b):
    return  a / b

def exp_fun(x,y):
    return div(x, y) * 2

def main(x,y ):
    exp_fun(x, y)
main(2, 0 )

---------------------------------------------------------------------------

ZeroDivisionError Traceback (most recent call last)

in ()
7 def main(x,y ):
8 exp_fun(x, y)
----> 9 main(2, 0 )

in main(x, y)
6
7 def main(x,y ):
----> 8 exp_fun(x, y)
9 main(2, 0 )

in exp_fun(x, y)
3
4 def exp_fun(x,y):
----> 5 return div(x, y) * 2
6
7 def main(x,y ):

in div(a, b)
1 def div(a, b):
----> 2 return a / b
3
4 def exp_fun(x,y):
5 return div(x, y) * 2

ZeroDivisionError: division by zero

异常信息是以堆栈的形式被抛出的,因而是从下往上查看的。由执行结果看到,div函数中产生的异常通过div和exp_fun函数传播,exp_fun中的异常通过exp_fun和main函数传播,传递到函数调用处由解释器处理,最终抛出堆栈的异常信息。

2 . 异常实例

要求:对给定的数组,前后两个数组相除,若被除数为0,则通过自定义异常打印出异常信息,并加入异常数数组中,若被除数不为0,则为正常数,加入正常数数组中。最后打印出正常数和异常数。

num_list = [1,0,2,0,3,4]

class NumberException(object):
    def __init__(self):
        pass
    
    @staticmethod
    def num_operation():
        normal_num_list = []
        exc_num_list = []
        
        for item in range(num_list.__len__()):
            if item == num_list.__len__() -1:
                a, b = num_list[item], num_list[item]
            else:
                a, b = num_list[item + 1], num_list[item]
        
            try:
                a / b 
                ret_str = "第"+ str(item + 1) + "个数是正常数,值为:" + str(num_list[item])
                normal_num_list.append(ret_str)
            except ZeroDivisionError as e:
                exc_list = MyError(num_list[item].__str__())
                ret_str = "第"+ str(item + 1) + "个数是异常数,值为:" + str(exc_list)
                exc_num_list.append(ret_str)
                print(MyError(num_list[item].__str__()))
            
        return normal_num_list, exc_num_list

class MyError(Exception):
    def __init__(self, num):
        self.num = num
        
    def __str__(self):
        return "错误信息:除数为0."
    
if __name__ == "__main__":
    normal_num_list, exc_num_list = NumberException.num_operation()
    print("正常数组为:", normal_num_list)
    print("异常数组为:", exc_num_list)

错误信息:除数为0.
错误信息:除数为0.
正常数组为: ['第1个数是正常数,值为:1', '第3个数是正常数,值为:2', '第5个数是正常数,值为:3', '第6个数是正常数,值为:4']
异常数组为: ['第2个数是异常数,值为:错误信息:除数为0.', '第4个数是异常数,值为:错误信息:除数为0.']

posted @ 2020-04-09 11:09  sinlearn  阅读(322)  评论(0)    收藏  举报