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

相關文章
相關標籤/搜索