欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

14-面向对象3

程序员文章站 2022-07-05 11:43:02
__new__方法 __new__和__init__方法的作用 运行结果如下: 总结: __new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由python解释器自动提供 __new__方法必须要有返回值,返回实例化出来的实例,这点在自己实现__new__要特别注意,可以retur ......

__new__方法

__new__和__init__方法的作用

 11 class A(object):                 
 12     def __init__(self):          
 13         print("这是__init__方法")
 14                                  
 15     def __new__(cls):            
 16         print('这是__new__方法') 
 17         return object.__new__(cls)                                                                                                                                        
 18                                  
 19 A()  

运行结果如下:

这是__new__方法
这是__init__方法

总结:

  • __new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由python解释器自动提供
  • __new__方法必须要有返回值,返回实例化出来的实例,这点在自己实现__new__要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例
  • __init__有一个参数self,就是这个__new__方法返回的实例,__init__方法在__new__的基础上可以完成一些其他初始化的动作,__init__不需要返回值
  • 我们可以将类比作制造商,__new__方法就是前期的原材料购买环节,__init__方法就是在有原材料的基础上,加工,初始化商品环节

异常

异常介绍

当python检测到一个错误的时候,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”

举例说明:

print ('------test1-------')
open('123.txt','r')       
print ('------test2-------') 

运行结果如下:

------test1-------
Traceback (most recent call last):
  File "05-异常.py", line 12, in <module>
    open('123.txt','r')
FileNotFoundError: [Errno 2] No such file or directory: '123.txt'

说明:打开一个不存在的文件123.txt,当找不到123.txt文件时,就会抛出给我们一个FileNotFoundError类型的错误No such file or directory: '123.txt'(没有123.txt这样的文件或目录)

捕获异常try...except...

看一下示例:

 11 try: 
 12     print('-------test1---------')                                                       
 13     open('123.txt','r')
 14     print('-------test2---------')
 15 except FileNotFoundError:
 16     print('文件没有找到')

运行结果如下:

-------test1---------
文件没有找到

说明:

  • 此程序在运行过程中抛出FileNotFoundError类型的错误,我们用了except添加了处理方法

总结:

把可能出现问题的代码放到try中

把处理异常的代码放到exvept中

except捕获多个异常

看如下示例:

 

 11 try:          
 12     print(num)                                                                           
 13 except FileNotFoundError:
 14     print('产生错误')

 

运行结果如下:

Traceback (most recent call last):
  File "07-捕获多个异常.py", line 12, in <module>
    print(num)
NameError: name 'num' is not defined

我们都已经用except来捕获异常了,那么为什么还会产生错误呢?

因为except捕获的是FileNotFoundError异常信息,没有NameError,所以程序才会出错

修改后的代码如下:

 11 try:            
 12     print(num)  
 13 except NameError:                                                                        
 14     print('产生错误')

运行结果如下:

产生错误

在实际开发过程中,捕获多个异常是这样的:

 11 try:             
 12     print('-------test1---------') 
 13     open('123.txt','r')
 14     print('-------test2---------') 
 15     print(num)   
 16 except (FileNotFoundError,NameError):
 17     print(errorMsg)

运行结果为:

-------test1---------
Traceback (most recent call last):
  File "06-捕获异常.py", line 13, in <module>
    open('123.txt','r')
FileNotFoundError: [Errno 2] No such file or directory: '123.txt'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "06-捕获异常.py", line 21, in <module>
    print(errorMsg)
NameError: name 'errorMsg' is not defined

注意:

  • 当捕获多个异常的时候,可以把要捕获的异常的名字,放到except后面,并使用元组的方式进行存储

获取异常的信息描述

In [1]: try:
   ...:     print(num)
   ...: except NameError as result:    #as result存储异常的基本信息
   ...:     print(result)
   ...:     
name 'num' is not defined

捕获所有异常

没有存储异常的基本信息

In [1]: try:
   ...:     open('a.txt')
   ...: except:
   ...:     print('产生了一个异常')
   ...:     
产生了一个异常

捕获所有异常,并且存储异常的基本信息

In [2]: try:
   ...:     open('a.txt')
   ...: except Exception as result:
   ...:     print('捕获到了异常')
   ...:     print(result)
   ...:     
捕获到了异常
[Errno 2] No such file or directory: 'a.txt'

else

我们对else应该不陌生,在if中,它的作用是当条件不满足时执行的实行,同样在try...except中也是如此,即如果没有捕获到异常,那么就需要执行else的事情

In [4]: try:
   ...:     num = 100
   ...:     print(num)
   ...: except NameError as result:
   ...:     print('捕获到了异常')
   ...:     print(result)
   ...: else:
   ...:     print('没有捕获到异常,真开心')
   ...:     
100
没有捕获到异常,真开心

try...finally...

在程序中,如果一个段代码必须要执行,即无论异常是否产生都要执行,那么此时就需要使用finally。比如关闭文件,释放锁,把数据库连接返回给连接池等

举例说明:

  1 #!/usr/bin/python                                                                                   
  2 #coding=utf8
  3 """
  4 # Author: xiaoyafei
  5 # Created Time : 2018-04-08 18:46:34
  6  
  7 # File Name: 08-try_finally.py
  8 # Description:
  9  
 10 """
 11 import time
 12 try:
 13     f = open('test.txt')
 14     try:
 15         while True:
 16             content = f.readline()
 17             if len(content)==0:
 18                 break
 19             time.sleep(2)
 20             print(content)
 21     except:
 22         #如果在读取文件的过程中产生了异常,那么就会捕捉到
 23         #比如,按下了ctrr+c
 24         pass
 25     finally:
 26         f.close()
 27         print('文件已正常关闭')
 28 except:
 29     print('没有这个文件')

然后, 需要在当前目录下touch文件test.txt,然后再运行,运行结果如下:

文件已正常关闭

说明:

  • test.txt文件中每一行数据打印,但是可以在每次打印的时候暂停2秒,这样的做法就是让程序运行慢一点,在程序运行的时候,可以ctrl+c中断程序
  • 当按下ctrl+c的时候,异常被触发,程序退出,但是在退出程序之间,finally从句依然被执行把文件关闭

异常的嵌套

try嵌套

  1 #!/usr/bin/python
  2 #coding=utf8
  3 """  
  4 # Author: xiaoyafei
  5 # Created Time : 2018-04-08 18:46:34
  6      
  7 # File Name: 08-try_finally.py
  8 # Description:
  9      
 10 """  
 11 import time
 12 try: 
 13     f = open('test.txt')
 14     try:
 15         while True:
 16             content = f.readline()
 17             if len(content)==0:
 18                 break
 19             time.sleep(2)
 20             print(content)
 21     except:
 22         #如果在读取文件的过程中产生了异常,那么就会捕捉到
 23         #比如,按下了ctrr+c
 24         pass
 25     finally:                                                                                                       
 26         f.close()
 27         print('文件已正常关闭')
 28 except:
 29     print('没有这个文件')

需要在当前目录下touch test.txt,然后在里面随便写点东西,运行结果如下:

aaaaaaaaaaaaaaaaaaaa

^C文件已正常关闭    #ctrl+c

函数嵌套调用中

  1 #!/usr/bin/python
  2 #coding=utf8
  3 """      
  4 # Author: xiaoyafei
  5 # Created Time : 2018-04-08 19:01:45
  6          
  7 # File Name: 09-异常的传递-函数调用中.py
  8 # Description:
  9          
 10 """      
 11 def test1():
 12     print('----------test1-1---------')
 13     print(num)
 14     print('----------test1-2---------')
 15          
 16 def test2():
 17     print('----------test2-1---------')
 18     test1()
 19     print('----------test2-2---------')
 20          
 21 def test3():
 22     try: 
 23         print('----------test3-1---------')
 24         test1()
 25         print('----------test3-2---------')                                                                        
 26     except Exception as result:
 27         print('捕获到了异常,信息是:%s'%result)
 28          
 29     print('----------test3-2---------')
 30          
 31 test3()  
 32 print('------------------华丽的分割线---------------')
 33 test2()  

运行结果如下:

----------test3-1---------
----------test1-1---------
捕获到了异常,信息是:name 'num' is not defined
----------test3-2---------
------------------华丽的分割线---------------
----------test2-1---------
----------test1-1---------
Traceback (most recent call last):
  File "09-异常的传递-函数调用中.py", line 33, in <module>
    test2()
  File "09-异常的传递-函数调用中.py", line 18, in test2
    test1()
  File "09-异常的传递-函数调用中.py", line 13, in test1
    print(num)
NameError: name 'num' is not defined

当调用test3函数时,在test1的函数内部产生了异常,此异常会被传递到test3函数中完成了异常处理,而当异常处理完后,并没有返回到函数test1中进行执行,而是在函数test3中继续执行

总结:

  • 如果try嵌套,那么如果里面的try没有捕获到这个异常,那么外面的try会接收到这个异常,然后进行处理,如果外边的try依然没有捕获到,那么再进行传递...
  • 如果一个异常实在一个函数中产生的,例如函数A-->函数B-->函数C-->,而异常是在函数 C中产生的,那么如果函数C中没有对这个异常进行处理,那么这个异常就会传递给B,如果函数B有异常处理那么则会按照函数B的处理方式进行执行;如果函数B也没有异常处理,那么这个异常会继续传递,以此类推......

抛出自定义的异常

可以用raise语句来引发一个异常。异常/错误对象必须要有一个名字,且他们应该是Error或Exception类的子类

下面是一个引发异常的例子:

  1 #!/usr/bin/python         
  2 #coding=utf8              
  3 """                       
  4 # Author: xiaoyafei       
  5 # Created Time : 2018-04-08 19:14:00
  6                           
  7 # File Name: 10-抛出自定义的异常.py
  8 # Description:            
  9                           
 10 """                       
 11 class ShortInputError(Exception):
 12     '''自定义的异常类'''  
 13     def __init__(self,length,alteast):
 14         super().__init__()                                                                                         
 15         self.length = length
 16         self.alteast = alteast
 17                           
 18 def main():               
 19     try:                  
 20         s = input('请输入----->')
 21         if len(s)<3:      
 22             #raise引发一个自定义的异常
 23             raise ShortInputError(len(s),3)
 24     except ShortInputError as result:
 25         print('ShortInputError:输入的长度是%d,长度至少是%d'%(result.length,result.alteast))
 26     else:                 
 27         print('没有异常') 
 28 main() 

运行结果如下:

python@ubuntu:~/codes/python基础-09$ python3 10-抛出自定义的异常.py 
请输入----->
ShortInputError:输入的长度是0,长度至少是3
python@ubuntu:~/codes/python基础-09$ python3 10-抛出自定义的异常.py 
请输入----->a
ShortInputError:输入的长度是1,长度至少是3
python@ubuntu:~/codes/python基础-09$ python3 10-抛出自定义的异常.py 
请输入----->bd 
ShortInputError:输入的长度是2,长度至少是3
python@ubuntu:~/codes/python基础-09$ python3 10-抛出自定义的异常.py 
请输入----->dad
没有异常

在以上代码中,关于suprt().__init__()的说明:

这一行代码,可以调用也可以不调用,建议调用,因为__init__方法 往往是用来创建完对象进行初始化工作,如果在子类中重写了父类的__init__方法,即意味着父类中的很多初始化工作没有做,这样就不能保证程序的稳定了,所以在以后的开发过程中,如果重写了父类的__init__方法,最好是先调用父类的这个方法,然后再添加自己的功能

异常处理中抛出异常

#!/usr/bin/python
#coding=utf8
"""
# Author: xiaoyafei
# Created Time : 2018-04-08 19:25:59
 
# File Name: 11-异常处理中抛出异常.py
# Description:
 
"""
class Test(object):
    def __init__(self,switch):
        self.switch = switch    #开关
    def cacl(self,a,b):
        try:
            return a/b
        except Exception as result:
            if self.switch:
 
                print('捕获开启,已经捕获到了异常,信息如下:')
                print(result)
            else:
                #重新抛出这个异常,此时就不会被这个异常给捕获到,从而触发默认的异常处理
                raise
a = Test(True)
a.cacl(11,0)
print('--------------------------华丽的分割线--------------------------')
a.switch = False
a.cacl(11,0)

运行结果如下:

捕获开启,已经捕获到了异常,信息如下:
division by zero
--------------------------华丽的分割线--------------------------
Traceback (most recent call last):
  File "11-异常处理中抛出异常.py", line 29, in <module>
    a.cacl(11,0)
  File "11-异常处理中抛出异常.py", line 16, in cacl
    return a/b
ZeroDivisionError: division by zero