zoukankan      html  css  js  c++  java
  • Python异常和调试.md

    异常捕获

    try

    基本概念

    我们使用try except来捕获异常,python的try except有几个特点:

    • 不管函数内部嵌套几层,只要在try的范围内就可以被捕获。这句话的意思是一个函数被try语句包裹,这个函数中调用了另一个函数。如果被调用函数中发生了异常,那么在外层的函数中是可以被捕获到的;

    特点

    • try except finally的执行逻辑是
      ** 正常逻辑是try -》finally
      ** 错误逻辑是try -》except -》finally

    except

    基本概念

    except中有各种类型的异常,其中基类是BaseException。具体可以参考:https://docs.python.org/3/library/exceptions.html#exception-hierarchy

    BaseException
    +-- SystemExit
    +-- KeyboardInterrupt
    +-- GeneratorExit
    +-- Exception
    +-- StopIteration
    +-- StopAsyncIteration
    +-- ArithmeticError
    | +-- FloatingPointError
    | +-- OverflowError
    | +-- ZeroDivisionError
    +-- AssertionError
    +-- AttributeError
    +-- BufferError
    +-- EOFError
    +-- ImportError
    +-- ModuleNotFoundError
    +-- LookupError
    | +-- IndexError
    | +-- KeyError
    +-- MemoryError
    +-- NameError
    | +-- UnboundLocalError
    +-- OSError
    | +-- BlockingIOError
    | +-- ChildProcessError
    | +-- ConnectionError
    | | +-- BrokenPipeError
    | | +-- ConnectionAbortedError
    | | +-- ConnectionRefusedError
    | | +-- ConnectionResetError
    | +-- FileExistsError
    | +-- FileNotFoundError
    | +-- InterruptedError
    | +-- IsADirectoryError
    | +-- NotADirectoryError
    | +-- PermissionError
    | +-- ProcessLookupError
    | +-- TimeoutError
    +-- ReferenceError
    +-- RuntimeError
    | +-- NotImplementedError
    | +-- RecursionError
    +-- SyntaxError
    | +-- IndentationError
    | +-- TabError
    +-- SystemError
    +-- TypeError
    +-- ValueError
    | +-- UnicodeError
    | +-- UnicodeDecodeError
    | +-- UnicodeEncodeError
    | +-- UnicodeTranslateError
    +-- Warning
    +-- DeprecationWarning
    +-- PendingDeprecationWarning
    +-- RuntimeWarning
    +-- SyntaxWarning
    +-- UserWarning
    +-- FutureWarning
    +-- ImportWarning
    +-- UnicodeWarning
    +-- BytesWarning
    +-- ResourceWarning

    
    

    特点

    异常的特点有:

    • 父类的异常捕获到,其后如果有子类也捕获异常,那么子类的异常捕获是失效的
    • 堆栈是按照顺序抛出异常的,在出错的时候可以顺着异常堆栈排查
    'a demo class of except'
    
    __author__ = 'liyue'
    
    class  MyExceptionTest:
        #通过try except finally处理异常
        def fun1(self):
            try:
                print('begin to calc 10/0:')
                i = 10/0
                print('calc successful')
            except ZeroDivisionError as e:
                print('ValueError:', e)
            finally:
                print('calc finally')
    
        #父类捕获异常,子类无效
        def fun2(self):
            try:
                print('begin to calc 10/0:')
                i = 10/0
                print('calc successful')
    
            except BaseException as be:
                print('This is BaseException :%s' % be) 
            except ZeroDivisionError as e:
                print('This is ValueError:%s' % e)
    
            finally:
                print('calc finally')
    
                
    
    if __name__ == '__main__':
        m = MyExceptionTest()
        m.fun1()
        m.fun2()
    
    

    记录异常

    • 记录异常可以用python內建logging模块,通过配置可以把logging信息记录到日志中。
    • 如果有logging,异常打印后,logging记录完后会继续执行完后续代码
    #logging记录异常
        def fun3(self):
            try:
                print('fun3:')
                print('begin to calc 10/0:')
                i = 10/0
                print('calc successful')
            except ZeroDivisionError as e:
                logging.exception(e)
            finally:
                print('3 calc finally')
    

    抛出错误

    我们使用raise来抛出错误,特点有:

    • 可以自定义抛出,但是前提是没有內建异常,或者实际需要
    • 可以在except中把适当的exception转换为另一个种抛出,前提是这种转换合理的
    'a demo class of except'
    __author__ = 'liyue'
    
    import logging
    
    class MyError(ValueError):
        pass
    
    class  MyExceptionTest:
        #通过try except finally处理异常
        def fun1(self, n):
            if n==0:
                raise MyError('This is my error')
            return 10/n
    
    if __name__ == '__main__':
        m = MyExceptionTest()
        m.fun1(0)
    
    

    调试

    print()

    print()方法是最常见的调试,在调试中直接打印信息,但是需要每次编码,且最终使用中不方便

    assert()

    断言也是一种通用的调试方法,但是不友好。使用也不方便

    pdb

    调试需要配置环境和下载pdb,开发阶段配置好可用,但是不具有通用性。

    logging

    日志是最有效最通用的方式,既可以调试也可以在非调试环境下使用。
    日志的配置有多种形式,api里有说明。这里取了最常用的。多模块可配置打印:

    'a demo class of except'
    __author__ = 'liyue'
    
    import logging
    #logging.basicConfig(filename='d:example.log',level=logging.DEBUG) #简单的打印
    #常见的通用打印,包含了输出路径、输出名称、级别、时间和信息
    logging.basicConfig(filename='d:example.log', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
    
    class MyDebug(object):
    
        def assertTest(self, n):
            if n == 0:
                assert()
    
        def logTest(self, msg):
            #这两句是单模块打印时候使用,如果设计中不需要模块信息输出也可以直接这样使用
            #logging.info(msg)
            #logging.debug(msg)
    
            #更为通用的多模块打印,是常见的打印模式
            logger = logging.getLogger('ly demo')
            logger.warning(msg)
    
    if __name__ == '__main__':
        m = MyDebug()
        #m.assertTest(0)
        m.logTest('This is a test log info')
        m.logTest('print some infomation')
    
    
    
  • 相关阅读:
    Space Ant(极角排序)
    Marriage Match II(二分+并查集+最大流,好题)
    Leapin' Lizards(经典建图,最大流)
    Food(最大流)
    99. Recover Binary Search Tree
    97. Interleaving String
    100. Same Tree
    98. Validate Binary Search Tree
    95. Unique Binary Search Trees II
    96. Unique Binary Search Trees
  • 原文地址:https://www.cnblogs.com/bugstar/p/8033878.html
Copyright © 2011-2022 走看看