zoukankan      html  css  js  c++  java
  • day27:异常&反射

    目录

    认识异常处理

      1.程序错误的种类

        2.异常的分类

      3.AssertionError(断言assert语句失败)

    异常处理的基本语法

      1.异常处理的基本语法

      2.带有分支的异常处理

      3.处理迭代器异常错误

    异常处理的其他写法

      1.try ... finally ...

      2.try ... except ... else ...

      3.try ... except ... else ... finally ...

    raise:主动抛出异常

      1.关于raise你需要知道

      2.raise的基本语法

    自定义异常类

    反射

      1.反射类当中的成员

      2.反射模块当中的成员

      3.反射综合案例

    认识异常处理

    1.程序错误的种类

    程序错误分为两种:语法错误异常错误

    1.语法错误:代码没有按照python规定语法去写,发明创造产生的错误

    2.异常错误:在代码语法正确的前提下,程序报错就是异常

    2.异常的分类

    # IndexError                索引超出序列的范围
    # KeyError                  字典中查找一个不存在的关键字
    # NameError                 尝试访问一个不存在的变量
    # IndentationError          缩进错误
    # AttributeError            尝试访问未知的对象属性
    # StopIteration             迭代器没有更多的值
    # AssertionError             断言语句(assert)失败
    # EOFError                  用户输入文件末尾标志EOF(Ctrl+d)
    # FloatingPointError        浮点计算错误
    # GeneratorExit             generator.close()方法被调用的时候
    # ImportError               导入模块失败的时候
    # KeyboardInterrupt         用户输入中断键(Ctrl+c)
    # MemoryError               内存溢出(可通过删除对象释放内存)
    # NotImplementedError       尚未实现的方法
    # OSError                   操作系统产生的异常(例如打开一个不存在的文件)
    # OverflowError             数值运算超出最大限制
    # ReferenceError            弱引用(weak reference)试图访问一个已经被垃圾回收机制回收了的对象
    # RuntimeError              一般的运行时错误
    # SyntaxError               Python的语法错误
    # TabError                  Tab和空格混合使用
    # SystemError               Python编译器系统错误
    # SystemExit                Python编译器进程被关闭
    # TypeError                 不同类型间的无效操作
    # UnboundLocalError         访问一个未初始化的本地变量(NameError的子类)
    # UnicodeError              Unicode相关的错误(ValueError的子类)
    # UnicodeEncodeError        Unicode编码时的错误(UnicodeError的子类)
    # UnicodeDecodeError        Unicode解码时的错误(UnicodeError的子类)
    # UnicodeTranslateError     Unicode转换时的错误(UnicodeError的子类)
    # ValueError                传入无效的参数
    # ZeroDivisionError         除数为零

    3.AssertionError(断言assert语句失败)

    什么是断言?

    断言就是的意思

    assert 和 if 之间的区别在于

    assert 在断言失败时候,是直接报错,抛出异常,后面的代码直接终止

    if 在判断为False 的时候,不执行代码

    assert 3>1
    assert 3>1000
    print("ok")

     异常处理的基本语法

    1.异常处理的基本语法

    try ... except ...

    有问题的代码放到try这个代码块当中

    如果出现了异常,会直接执行except这个代码块中的内容

    作用:防止异常抛错,终止程序.

    try :
        lst = [1,2,3]
        print(lst[90])
    except:
        print("这里有异常错误~")

    2.带有分支的异常处理

    在说这个之前,先说一个语法:

    except + 异常错误类:特指发生在这类异常错误时,要执行的分支

    try:
        # IndexError
        # lst = [1,2,3]
        # print(lst[90])
        
        # KeyError
        # dic = {}
        # print(dic["a"])
        
        # NameError
        # print(wangwen)
        
    except IndexError:
        print("索引超出了范围")
        
    except KeyError:
        print("字典中没有这个键")
    
    except NameError:
        print("没有这个变量")
    
    except:
        print("有异常错误...")

    :)看这个结构,有些像 if elif elif else的感觉

    3.处理迭代器异常错误

    def mygen():
        print("start ... ")
        yield 1
        yield 2
        yield 3
        return 4
    
    gen = mygen()
    try:
        res = next(gen)
        print(res)
        res = next(gen)
        print(res)
        res = next(gen)
        print(res)
        res = next(gen)
        print(res)
        
    except StopIteration as e :
        # 为当前异常错误类StopIteration的对象起一个别名叫做e
        # 在StopIteration内部有__str__的方法
        # 在打印对象时,直接获取生成器中的return的返回值.
        print(e)
        print("生成器停止迭代")

    看到了这段代码,有几个问题需要注意:

    1.except StopIteration as e:StopIteration是一个异常错误类,e是错误类对象的别名

    2.在StopIteration异常类中,内置了__str__方法,在打印e对象时,可以直接获取到生成器中的return返回值

    异常处理的其他写法

    1.try ... finally ...

    不论代码正确与否,都必须执行的代码放到finally当中.

    一报错会终止掉程序,后面的代码不执行

    有些必须要走的代码写在finally中

    try:
        lst = [1,2,3]
        print(lst[90])
    finally:
        print("被触发了..")
    
    print(123)

    2.try ... except ... else ...

    如果try这个代码块没有异常错误,执行else这个分支,反之就不执行

    try:
        lst = [1,2,3]
        print(lst[90])
    except:
        pass
    else:
        print("正常执行结束...")

    3.try ... except ... else ... finally ...

    try内代码块的代码如果有异常,执行except代码块

                             如果没有异常,执行else代码块

            不管有没有异常,最后都要走finally代码块

    try:
        lst = [1,2,3]
        print(lst[90])
    except:
        print("异常处理222")
    else:
        print("正常执行结束...")
    finally:
        print("我被执行了111")

    raise:主动抛出异常

    关于raise你需要知道

    基本格式:raise + 异常错误 or 异常错误类对象

    常见的两个父类:

      BaseException 所有异常类的父类(基类,超类)

      Exception 常见异常类的父类

    raise的基本语法

    # 基本语法
    try:
        raise BaseException # 相当于主动制造出一个错误
    except BaseException:
        pass
        
    # 简写
    try:
        raise
    except:
        print("有异常错误")

    自定义异常类

    定义一个自定义异常类MyException,让此类继承BaseException类

    #(了解)系统底层获取行数和文件名的函数( 只有在程序异常时才能触发 ) 
    def return_errorinfo(n):
        import sys
        f = sys.exc_info()[2].tb_frame.f_back
        if n==1:        
            return str(f.f_lineno)      #返回当前行数
        elif n == 2:    
            return f.f_code.co_filename #返回文件名    
    
    
    def get_value(n):
        try:
            raise
        except:
            return return_errorinfo(n)
    
    
    class MyException(BaseException):
        def __init__(self,num,msg,line,file):
            # 错误号
            self.num = num
            # 错误信息
            self.msg = msg
            # 错误行号
            self.line = line
            # 错误文件
            self.file = file
    
    
    sex = "雌雄同体"
    try:
        if sex == "雌雄同体":
            # raise + 异常错误类 或者 异常错误类对象
            raise MyException(404,"醒醒吧老弟,人类没有雌雄同体~",get_value(1),get_value(2))
    
    except MyException as e:
        # 对象.属性 
        print(e.num)
        print(e.msg)
        print(e.line)
        print(e.file)
        
        

    反射

    概念: 通过字符串去操作类对象或者模块当中的成员(属性或者方法)

    class Man():
        pass
    
    class Woman():
        pass
    
    class Children(Man,Woman):
        skin = "绿色"
        
        def eat(self):
            print("小孩一下生就拿了两串大腰子出来了")
    
        def drink(self):
            print("小孩一下生拿了两瓶勇闯天涯出来了")
        
        def __suger(self):
            print("小孩自个的糖糖是不给别人的...")
            
    obj = Children()

    1.反射类当中的成员

    1.hasattr() 检测对象/类是否有指定的成员

    # hasattr() 检测对象/类是否有指定的成员
    # 对象
    res = hasattr(obj,"skin") # 检测obj对象是否有成员skin
    print(res)
    
    #
    res = hasattr(Children,"eat") # 也可以检测类中是否有成员eat
    res = hasattr(Children,"__suger") # 私有成员不能访问,所以结果为False
    print(res)

    2.getattr() 获取对象/类成员的

    # getattr() 获取对象/类成员的值
    # 对象
    res = getattr(obj,"skin") # 对象反射属性
    print(res)
    
    # 通过对象反射出来的方法是个绑定方法,不需要在func添加参数,obj会自动传进去
    func = getattr(obj,"drink")
    func()
    
    #
    # 通过类反射出来的方法是个普通方法,需要添加参数,避免形参实参数量不一致
    func = getattr(Children,"eat")
    func(1)
    
    # 反射的成员不存在时,可以设置一个默认值防止报错
    res = getattr(obj,"abcdefg1234","该成员不存在")
    print(res)

    3.setattr() 设置对象/类成员的值

    # 对象
    setattr(obj,"eye","白色")
    print(obj.eye)
    
    #
    setattr(Children,"sex","女性")
    print(Children.sex)
    print(obj.sex)

    4.delattr() 删除对象/类成员的值 

    delattr(obj,"eye")
    print(obj.eye)  # error
    
    #
    delattr(Children,"sex")
    Children.sex

    2.反射模块当中的成员

    import sys
    print(sys.modules) # 返回的是系统模块的一个字典
    
    # 获取当前本模块的对象 (通过__main__这个键来获取)
    print(sys.modules["__main__"])
    # <module '__main__' from '/mnt/hgfs/python31_gx/day27/mymodule4.py'>
    
    
    
    def func1():
        print("我是func1方法")
    
    def func2():
        print("我是func2方法")
    
    def func3():
        print("我是func3方法")
    
    def func4():
        print("我是func4方法")

    3.反射综合案例

    while True:
        selfmodule = sys.modules["__main__"] # 获取当前模块对象
        strvar = input("请输入你要反射的方法")
        if hasattr(selfmodule,strvar): # 判断当前模块是否有你输入的方法
            func = getattr(selfmodule,strvar) # 获取到你输入的方法名
            func()
        else:
            print("没有这个方法")
  • 相关阅读:
    小程序40001错误
    【2020-06-07】把心思放在赚钱上就对了
    【2020-06-05】下点功夫,看清题目,并做好选择
    【2020-06-04】人生十三信条
    【2020-06-03】顺境时也需要放空
    【2020-06-02】我感染别人的同时,也加强了自己的信念
    【2020-06-01】信息的吸收源自压力
    【一句日历】2020年6月
    【2020-05-30】向风、向雨、向阳光去讨教
    【2020-05-29】爱眼前的一切
  • 原文地址:https://www.cnblogs.com/libolun/p/13472339.html
Copyright © 2011-2022 走看看