Python基础_异常处理与跟踪

 

异常的种类

AttributeError 试图访问一个对象没有的树形,好比foo.x,可是foo没有属性x
IOError 输入/输出异常;基本上是没法打开文件
ImportError 没法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,好比当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(我的认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是因为另有一个同名的全局变量,
致使你觉得正在访问它
ValueError 传入一个调用者不指望的值,即便值的类型是正确的
经常使用异常
ArithmeticError
AssertionError
AttributeError
BaseException
BufferError
BytesWarning
DeprecationWarning
EnvironmentError
EOFError
Exception
FloatingPointError
FutureWarning
GeneratorExit
ImportError
ImportWarning
IndentationError
IndexError
IOError
KeyboardInterrupt
KeyError
LookupError
MemoryError
NameError
NotImplementedError
OSError
OverflowError
PendingDeprecationWarning
ReferenceError
RuntimeError
RuntimeWarning
StandardError
StopIteration
SyntaxError
SyntaxWarning
SystemError
SystemExit
TabError
TypeError
UnboundLocalError
UnicodeDecodeError
UnicodeEncodeError
UnicodeError
UnicodeTranslateError
UnicodeWarning
UserWarning
ValueError
Warning
ZeroDivisionError
更多异常

异常处理

异常语法

# python3语法
try:
    pass
except Exception as e:
    pass



# python2语法
try:
    pass
except Exception,e:
    pass
通常语法  try...except as e...
s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
多分支异常  try...except as e...except as e...
try:
    pass
except:
    pass


try:
    pass
except Exception as e:
    print(e)
    
    
try:
    pass
except ValueError as e:
    pass
except IndexError as e:
    pass
except Exception as e:
    pass
万能异常 try...except...
try:
    print("try")
except KeyError as e:
    # 异常时,执行该块
    pass
else:
    # 主代码块执行完,执行该块
    print("else")
finally:
    # 不管异常与否,最终执行该块
    print("finally")

"""
try
else
finally
"""



try:
    print("try")
    raise KeyError
except KeyError as e:
    # 异常时,执行该块
    print("KeyError")
else:
    # 主代码块执行完,执行该块
    print("else")
finally:
    # 不管异常与否,最终执行该块
    print("finally")
    
"""
try
KeyError
finally
"""
try...except...else...finally
try:
    raise Exception('错误了。。。')
except Exception as e:
    print(e)
    
"""
错误了。。。
"""
主动触发异常
class MyException(Exception):

    def __init__(self, msg):
        self.message = msg

    def __str__(self):
        return self.message


try:
    raise MyException('个人异常')
except MyException as e:
    print(e)
自定义异常

 断言 assert

assert 1 == 1
# True,则执行后面代码

assert 1 == 2  # 报错
"""
Traceback (most recent call last):
  File "D:/Python相关/test.py", line 6, in <module>
    assert 1 == 2
AssertionError
"""


try:
    assert 1 == 2
except AssertionError as e:
    print("AssertionError")

断言 assert
断言 assert

异常跟踪

traceback模块

# 通常的异常处理
try:
    1 / 0
except Exception as e:
    print(e)
# division by zero


# 配合traceback进行异常跟踪
import traceback
try:
    1 / 0
except Exception as e:
    # traceback.print_exc()  # 打印出来,无返回值,效果等于print(traceback.format_exc())
    res = traceback.format_exc()
    print(res)

"""
Traceback (most recent call last):
  File "D:/Python相关/项目/interview/test3.py", line 44, in <module>
    1 / 0
ZeroDivisionError: division by zero
"""

"""
traceback.print_exc()跟traceback.format_exc()有什么区别呢?
    traceback.print_exc()与print traceback.format_exc()效果是同样的。
    format_exc()返回字符串
    print_exc()则直接给打印出来。
    print_exc()还能够接受file参数直接写入到一个文件。好比traceback.print_exc(file=open('tb.txt','w+'))写入到tb.txt文件去。
"""
traceback简单使用
def func(a, b):
    return a / b


if __name__ == '__main__':
    import sys
    import traceback

    try:
        func(1, 0)
    except Exception as e:
        print("print_exception()")
        exc_type, exc_value, exc_tb = sys.exc_info()
        print('the exc type is:', exc_type)
        print('the exc value is:', exc_value)
        print('the exc tb is:', exc_tb)
        traceback.print_exception(exc_type, exc_value, exc_tb)
traceback简单使用2

使用cgitb来简化异常调试

若是平时开发喜欢基于log的方式来调试,那么可能常常去作这样的事情,在log里面发现异常以后,由于信息不足,那么会再去额外加一些debug log来把相关变量的值输出。调试完毕以后再把这些debug log去掉。其实不必这么麻烦,Python库中提供了cgitb模块来帮助作这些事情,它可以输出异常上下文全部相关变量的信息,没必要每次本身再去手动加debug log。html

cgitb的使用简单的不能想象:python

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


if __name__ == '__main__':
    import cgitb

    cgitb.enable(format='text')

    func(1, 0)

"""
A problem occurred in a Python script.  Here is the sequence of
function calls leading up to the error, in the order they occurred.

 /Users/samchi/Documents/workspace/tracebacktest/teststacktrace.py in <module>()
    4     import cgitb
    5     cgitb.enable(format='text')
    6     import sys
    7     import traceback
    8     func(1, 0)
func = <function func>

 /Users/samchi/Documents/workspace/tracebacktest/teststacktrace.py in func(a=1, b=0)
    2     return a / b
    3 if __name__ == '__main__':
    4     import cgitb
    5     cgitb.enable(format='text')
    6     import sys
a = 1
b = 0
"""
cgitb,覆盖了默认的sys.excepthook函数

彻底没必要再去log.debug("a=%d" % a)了,我的感受cgitb在线上环境不适合使用,适合在开发的过程当中进行调试,很是的方便。git

也许你会问,cgitb为何会这么屌?能获取这么详细的出错信息?其实它的工做原理同它的使用方式同样的简单,它只是覆盖了默认的sys.excepthook函数,sys.excepthook是一个默认的全局异常拦截器,能够尝试去自行对它修改:ide

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


def my_exception_handler(exc_type, exc_value, exc_tb):
    print("i caught the exception:", exc_type)
    while exc_tb:
        print("the line no:", exc_tb.tb_lineno)
        print("the frame locals:", exc_tb.tb_frame.f_locals)
        exc_tb = exc_tb.tb_next


if __name__ == '__main__':
    import sys

    sys.excepthook = my_exception_handler
    import traceback

    func(1, 0)

"""
i caught the exception: <class 'ZeroDivisionError'>
the line no: 35
the frame locals: {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x02FDB410>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/Python相关/项目/interview/test2.py', '__cached__': None, 'func': <function func at 0x0304B810>, 'my_exception_handler': <function my_exception_handler at 0x04C70618>, 'sys': <module 'sys' (built-in)>, 'traceback': <module 'traceback' from 'C:\\Python\\Python36\\lib\\traceback.py'>}
the line no: 18
the frame locals: {'b': 0, 'a': 1}
"""
sys.excepthook是一个默认的全局异常拦截器

 

使用logging模块来记录异常

import logging

try:
    1 / 0
except Exception as e:
    logging.exception(e)
    logging.error(e, exc_info=1)  # 指名输出栈踪影, logging.exception的内部也是包了一层此作法
    logging.critical(e, exc_info=1)  # 更加严重的错误级别
    
"""
ERROR:root:division by zero
Traceback (most recent call last):
  File "D:/Python相关/项目/interview/test2.py", line 20, in <module>
    1 / 0
ZeroDivisionError: division by zero
ERROR:root:division by zero
Traceback (most recent call last):
  File "D:/Python相关/项目/interview/test2.py", line 20, in <module>
    1 / 0
ZeroDivisionError: division by zero
CRITICAL:root:division by zero
Traceback (most recent call last):
  File "D:/Python相关/项目/interview/test2.py", line 20, in <module>
    1 / 0
ZeroDivisionError: division by zero
"""
使用logging模块来记录异常

 

 

参考or转发

http://www.cnblogs.com/wupeiqi/articles/5017742.html函数

https://blog.csdn.net/lengxingxing_/article/details/56317838ui

相关文章
相关标签/搜索