zoukankan      html  css  js  c++  java
  • 鸭子类型-类的约束-异常处理

    封装,多态

    python三大特性: 继承,封装,多态

    多态:

    python默认支持多态

    一个事物可以拥有多种形态(一个变量名可以指向任何数据类型)

    鸭子类型

    python处处都是鸭子类型

    两个类中定义的几个方法名相同,两个类就互为鸭子

    class A:
        def add(self):
            print('增加')
    
        def delete(self):
            print('删除')
    
    class B:
        def add(self):
            print('这也是增加')
    
        def delete(self):
            print('这也是删除')
    
        def update(self):
            pass

    两个类中方法名一样,两个类虽然没有任何关系,但是隐形中遵循了一个标准:

    1.统一标准,减少词汇量,建立了弱关联

    2.A和B没有任何耦合性,但是可以产生关系A的对象使用B类的方法

    super()方法

    super可以执行非本方法的方法

    super(指定类名,self)  跳过指定类名

    super()是完全按照对象self所在类的mro的顺序执行的

    class A:
        def func1(self):
            print('in A func1')
    
    class B(A):
        def func1(self):
            super().func1()      #super(B,self).func1()  跳过B类,按照mro顺序执行
            print('in B func1')
    
    class C(A):
        def func1(self):
            print('in C func1')
    
    class D(B,C):
        def func1(self):
            super().func1()      #super(D,self).func1()  跳过D类,按照mro顺序执行
            print('in D func1')
    
    obj = D()
    obj.func1()
    print(D.mro())    #mro顺序D B C A
    
    结果:
    in C func1
    in B func1
    in D func1

    类的约束

    指定一个强制的标准,强制子类要有父类规定的方,python提供两种解决方式:

    方法一:在父类的方法中主动抛出异常(常用)   raise

    class Payment:
        def pay(self,money):
            raise Exception('子类要定义pay方法!!!')
    
    class Alipay(Payment):
        def pay(self,money):
            print('您用阿里支付了%s元' % money)
    
    class QQpay(Payment):
        def pay(self,money):
            print('您用QQ支付了%s元' % money)
    
    class Wechatpay(Payment):
        def pay(self,money):
            print('您用微信支付了%s元' % money)
    
    class Applepay(Payment):
        def zhifu(self,money):          #没有用pay方法,在使用父类pyment中的pay方法中,会因为raise主动报错
            print('您用苹果支付了%s元' % money)
    
    def pay(obj,money):                  # 统一了支付方式:归一化设计
        obj.pay(money)                   # obj2.pay(200)
    
    obj2 = Applepay()
    pay(obj2,200)

    方法二:引用抽象类,接口类

    制定一个规范,强制子类必须有一些方法,如果没有,在实例化的时候就会报错

    from abc import ABCMeta,abstractmethod      #固定格式
    class Payment(metaclass=ABCMeta):
        @abstractmethod
        def pay(self,money):
            pass
    
    class Alipay(Payment):
        def pay(self,money):
            print('您用阿里支付了%s元' % money)
    
    class QQpay(Payment):
        def pay(self,money):
            print('您用QQ支付了%s元' % money)
    
    class Wechatpay(Payment):
        def pay(self,money):
            print('您用微信支付了%s元' % money)
    
    class Applepay(Payment):
        def zhifu(self,money):
            print('您用苹果支付了%s元' % money)
    
    def pay(obj,money):   # 统一了支付方式:归一化设计
        obj.pay(money)    # obj2.pay(200)
    
    obj2 = Applepay()      #在实例化的时候会报错
    pay(obj2,200)

    异常处理

    异常错误分类:

    1.语法错误

    2.逻辑错误

    异常处理:先捕捉错误,再进行处理

    异常处理的两种方式:

    1.if

    劣势:

       1)对于相同的错误类型,要用大量的重复代码处理异常

       2)如果异常种类较多,利用if,代码量会出现冗余

    2.try except 异常处理

      1)单支

    try:
        a = 1
        b = 2
        l1 = [1,2,3]
        l1[100]             #索引错误  执行except
        print(111)
        dic = {}
        print(dic['key'])    #key错误
        print(111)
    except IndexError:
        print(666)

      2)多分支

    try:
        a = 1
        b = 2
        l1 = [1,2,3]
        l1[100]                     #索引错误
        print(111)
        dic = {}
        print(dic['key'])          #key错误
        num = input('>>>')
        int(num)                    #值错误
        print(222)
    except IndexError as e:    #可以不写 as e
        print(e)
    except KeyError as e:
        print(e)
    except ValueError as e:
        print(e)
    print(666)

      3)万能异常

    try:
    except Exception

    try:
        dic[num]()
        l1 = [1,2]
        l1[100]
    except Exception:
        print(666)

    结果:
    666

      4)多分支+万能

    如果只想将异常处理掉,对错误信息不关心,用万能异常.

    如果需要根据不同的错误信息而执行不同的逻辑(分流),用多分支,或者多分支加万能异常.

    while 1 :
        print("""
        1  登录
        2  注册
        3  转账
        4  存钱
        """)
        try:
            num = int(input('请输入选项'))
            dic[num]()
        except ValueError:           #当用户输入内容是非数字时
            print('请输入数字')  
        except KeyError:             #当用户输入内容超出现有序号时
            print('请输入正确序号')
        except Exception:            #出现其他未知错误时,万能异常处理,保证程序继续运行
            pass

      5) try except else

    如果出现异常,就不执行else,不出现异常执行else

    try:
        a                      #没有定义a,执行except进行异常处理,不执行else
        print(111)
        print(222)
    except Exception:
        print(333)
    else:
        print(666)
        
    结果:
    333

      6)try except (else) finally

    finally 出不出现异常都执行,异常出现前执行finally

    用途:

      关闭文件句柄,关闭数据库链接

      函数return之前能够执行finally代码

      在break之前能够执行finally代码

    try:
        dic = {}
        dic[100]          #keyerror
    except ValueError:
        print(333)
    finally:
        print(666)         #在报错之前执行
    
        
    def func():
        try:
            return 666
        finally:
            print(111)    #在return之前执行
    func()
    
    
    while 1:
        try:
            if 3 > 2:
                break
        finally:
            print(333)   #在break之前执行
            

      7) 主动抛出异常   raise

    raise IndexError('超出索引范围')

      8)断言   

    表示一个强硬的态度,不满足条件就直接报错

    assert 条件   条件不成立就报错

    class A:
        name = None
        def get(self):
            assert A.name is not None
            num = 123
            for i in range(10):
                num += i
            print(num)
    
    obj = A()
    # A.name = 'barry'     #当name为None时,会直接报错,当把'barry'传给name时,会执行for循环
    obj.get()

      9) 自定义异常

    出现的错误是python解释器没有定义的错误类型,自己手动定义

    # 手机连接问题
    class PhoneConnection(BaseException):
        pass
    try:
        raise PhoneConnection('手机连接错误')    #主动抛出异常
    except Exception as e:
        print(e)

     异常处理总结:

    1.异常处理不能经常使用,耗费性能,异常处理的分支越多,越冗余

    2.能用程序解决的问题,尽量用程序解决

    3.start文件中禁止使用

    异常处理的用法:

    1.一些无法预知的错误,要用异常处理

    2.如果程序此时需要通过if条件过滤掉很多不必要的因素,可以用异常处理

  • 相关阅读:
    华为机试练习(一)
    LM拟合算法
    5.1 模块化程序设计
    第3周 运算的流程控制
    KEGG数据库介绍
    topGO
    GO.db
    Bioconductor应用领域之基因芯片
    org.Hs.eg.db包简介(转换NCBI、ensemble等数据库中基因ID,symbol等之间的转换)
    Bioconductor的历史
  • 原文地址:https://www.cnblogs.com/sandy-123/p/10329531.html
Copyright © 2011-2022 走看看