自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

漲知識(shí)!Python 的異常信息還能這樣展現(xiàn)

開發(fā) 后端
在日常開發(fā)的過程中,當(dāng)代碼報(bào)錯(cuò)時(shí),我們通常要不斷打印、閱讀traceback提示信息,來調(diào)試代碼,這篇文章介紹了如何實(shí)現(xiàn)一個(gè)Exception Hooks,使得traceback模塊的提示信息更加精確;同時(shí)還介紹了一些第三方庫,這些庫也提供了Exception Hooks的功能。

簡介

在日常開發(fā)中,我們的大部分時(shí)間都會(huì)花在閱讀traceback模塊信息以及調(diào)試代碼上。本文我們將改進(jìn)traceback模塊,讓其中的提示信息更加簡潔準(zhǔn)確。

基于這一目的,我們將會(huì)自定義Exception Hooks(異常處理鉤子),用來去除traceback中的冗余信息,只留下解決報(bào)錯(cuò)所需的內(nèi)容。此外,我還會(huì)介紹一些好用的第三方庫,你可以直接使用其中的Exception Hooks,來簡化traceback模塊。

Exception Hooks

假如程序的異常信息沒有被try/catch捕獲到,python解釋器就會(huì)調(diào)用sys.excepthook()函數(shù),它會(huì)接收3個(gè)參數(shù),分別是:type, value, traceback。這個(gè)函數(shù)也被稱為Exception Hook,會(huì)輸出程序的異常信息。

我們來看看下面這個(gè)例子:

import sys
def exception_hook(exc_type, exc_value, tb):
print('Traceback:')
filename = tb.tb_frame.f_code.co_filename
name = tb.tb_frame.f_code.co_name
line_no = tb.tb_lineno
print(f"File {filename} line {line_no}, in {name}")
# Exception type 和 value
print(f"{exc_type.__name__}, Message: {exc_value}")
sys.excepthook = exception_hook

在這個(gè)例子中,我們可以從traceback (tb)對(duì)象中獲取到異常信息出現(xiàn)的位置,位置信息包括:文件名(f_code.co_filename),函數(shù)/模塊名(f_code.co_name), 和行數(shù)(tb_lineno)。此外,我們可以使用exc_type和exc_value變量來獲取異常信息的內(nèi)容。

當(dāng)我們調(diào)用一個(gè)會(huì)產(chǎn)生錯(cuò)誤的函數(shù)時(shí),exception_hook會(huì)輸出如下內(nèi)容:

def do_stuff():
# 寫一段會(huì)產(chǎn)生異常的代碼
raise ValueError("Some error message")
do_stuff()
# Traceback:
# File /home/some/path/exception_hooks.py line 22, in <module>
# ValueError, Message: Some error message

上述例子提供了一部分異常信息,但要想獲取調(diào)試代碼所需的全部信息,并知道異常出現(xiàn)的時(shí)間及位置,我們還需要深入研究下traceback對(duì)象:

def exception_hook(exc_type, exc_value, tb):
local_vars = {}
while tb:
filename = tb.tb_frame.f_code.co_filename
name = tb.tb_frame.f_code.co_name
line_no = tb.tb_lineno
print(f"File {filename} line {line_no}, in {name}")
local_vars = tb.tb_frame.f_locals
tb = tb.tb_next
print(f"Local variables in top frame: {local_vars}")
...
# File /home/some/path/exception_hooks.py line 41, in <module>
# File /home/some/path/exception_hooks.py line 7, in do_stuff
# Local variables in top frame: {'some_var': 'data'}

由上面的例子可以看出,traceback對(duì)象(tb)本質(zhì)上是一個(gè)鏈表 - 存儲(chǔ)著所有出現(xiàn)的exceptions。因此可以使用tb_next對(duì)tb進(jìn)行遍歷,并打印每一個(gè)異常的信息。在此基礎(chǔ)上,還可以使用tb_frame.f_locals屬性將變量輸出到console中,這有助于調(diào)試代碼。

使用traceback對(duì)象輸出異常信息是可行的,但是比較麻煩,此外輸出的信息可讀性較差。更方便的做法是使用traceback模塊,該模塊內(nèi)置了許多提取異常信息的輔助函數(shù)。

目前我們已經(jīng)介紹了Exception Hooks的基礎(chǔ)知識(shí),接下來我們可以自定義一個(gè)exception hooks,并加入一些實(shí)用的特性。

自定義Exception Hooks

  1. 我們還可以讓異常信息自動(dòng)存入文件中,在之后調(diào)試代碼的時(shí)候查看:
LOG_FILE_PATH = "./some.log"
FILE = open(LOG_FILE_PATH, mode="w")
def exception_hook(exc_type, exc_value, tb):
FILE.write("*** Exception: ***\n")
traceback.print_exc(file=FILE)
FILE.write("\n*** Traceback: ***\n")
traceback.print_tb(tb, file=FILE)
# *** Exception: ***
# NoneType: None
#
# *** Traceback: ***
# File "/home/some/path/exception_hooks.py", line 82, in <module>
# do_stuff()
# File "/home/some/path/exception_hooks.py", line 7, in do_stuff
# raise ValueError("Some error message")
  1. 異常信息默認(rèn)會(huì)存儲(chǔ)到stderr中,如果你想改變存儲(chǔ)位置,可以這樣做:
import logging
logging.basicConfig(
level=logging.CRITICAL,
format='[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s',
datefmt='%H:%M:%S',
stream=sys.stdout
)
def exception_hook(exc_type, exc_value, exc_traceback):
logging.critical("Uncaught exception:", exc_info=(exc_type, exc_value, exc_traceback))
# [17:28:33] {/home/some/path/exception_hooks.py:117} CRITICAL - Uncaught exception:
# Traceback (most recent call last):
# File "/home/some/path/exception_hooks.py", line 122, in <module>
# do_stuff()
# File "/home/some/path/exception_hooks.py", line 7, in do_stuff
# raise ValueError("Some error message")
# ValueError: Some error message
  1. 我們還可以給提示信息的某一部分設(shè)置顏色:
# pip install colorama
from colorama import init, Fore
init(autoreset=True) # Reset the color after every print
def exception_hook(exc_type, exc_value, tb):
local_vars = {}
while tb:
filename = tb.tb_frame.f_code.co_filename
name = tb.tb_frame.f_code.co_name
line_no = tb.tb_lineno
# Prepend desired color (e.g. RED) to line
print(f"{Fore.RED}File {filename} line {line_no}, in {name}")
local_vars = tb.tb_frame.f_locals
tb = tb.tb_next
print(f"{Fore.GREEN}Local variables in top frame: {local_vars}")

除了上面介紹的例子,你還可以輸出每一幀的局部變量,或者找到出現(xiàn)異常的行中所引用的變量。這些Exception Hooks已經(jīng)很成熟了,相比于自定義Exception hooks,我建議你閱讀下其他開發(fā)者的源碼,學(xué)習(xí)下他們的設(shè)計(jì)思路。

  •  輸出每一幀的局部變量[1]
  •  找到出現(xiàn)異常的行中所引用的變量[2]

第三方庫中的Exception Hooks

自定義一個(gè)Exception Hook很有趣,但許多第三方庫已經(jīng)實(shí)現(xiàn)這一功能了。與其自己造輪子,不如看看其他優(yōu)秀的工具。

  1. 首先,我個(gè)人最喜歡的是Rich,可以直接用pip進(jìn)行安裝,隨后導(dǎo)入使用。如果你只想在一個(gè)例子中使用,可以這樣做:python -m rich.traceback
# https://rich.readthedocs.io/en/latest/traceback.html
# pip install rich
# python -m rich.traceback
from rich.traceback import install
install(show_locals=True)
do_stuff() # Raises ValueError

  1. better_exceptions也很受歡迎,我們需要先設(shè)置環(huán)境變量BETTER_EXCEPTIONS=1,再用pip安裝。此外,如果你的TERM變量不是xterm,還要把SUPPORTS_COLOR設(shè)置為True。
# https://github.com/Qix-/better-exceptions
# pip install better_exceptions
# export BETTER_EXCEPTIONS=1
import better_exceptions
better_exceptions.MAX_LENGTH = None
# 檢查你的 TERM 變量是否被設(shè)置為 `xterm`, 如果沒有執(zhí)行以下操作
# See issue: https://github.com/Qix-/better-exceptions/issues/8
better_exceptions.SUPPORTS_COLOR = True
better_exceptions.hook()
do_stuff() # Raises ValueError

  1. 使用最方便的庫是pretty_errors,只需導(dǎo)入即可:
# https://github.com/onelivesleft/PrettyErrors/
# pip install pretty_errors
import pretty_errors
# 如果你對(duì)默認(rèn)配置滿意的話,則無需修改
pretty_errors.configure(
filename_display = pretty_errors.FILENAME_EXTENDED,
line_number_first = True,
display_link = True,
line_color = pretty_errors.RED + '> ' + pretty_errors.default_config.line_color,
code_color = ' ' + pretty_errors.default_config.line_color,
truncate_code = True,
display_locals = True
)
do_stuff()

除了直接導(dǎo)入外,上面的代碼還顯示了該庫的一些可選配置。更多的配置可以查看這里:配置[3]

  1. IPython的ultratb模塊
# https://ipython.readthedocs.io/en/stable/api/generated/IPython.core.ultratb.html
# pip install ipython
import IPython.core.ultratb
# Also ColorTB, FormattedTB, ListTB, SyntaxTB
sys.excepthook = IPython.core.ultratb.VerboseTB(color_scheme='Linux') # Other colors: NoColor, LightBG, Neutral
do_stuff()

  1. stackprinter庫
# https://github.com/cknd/stackprinter
# pip install stackprinter
import stackprinter
stackprinter.set_excepthook(style='darkbg2')
do_stuff()

結(jié)論

本文我們學(xué)習(xí)了如何自定義Exception Hooks,但我更推薦使用第三方庫。你可以在本文介紹的第三方庫中任選一個(gè)喜歡的,用到項(xiàng)目中。需要注意的是使用自定義Exception Hooks可能會(huì)丟失某些關(guān)鍵信息,例如:本文中的某些例子中,輸出中缺少文件路徑,在遠(yuǎn)程調(diào)試代碼這無疑很不方便,因此,需要謹(jǐn)慎使用。

責(zé)任編輯:龐桂玉 來源: Python頭條
相關(guān)推薦

2024-07-10 11:26:18

2019-01-29 10:00:59

GitHub開源搜索

2024-05-17 09:37:26

format屬性Spring

2020-10-12 06:28:05

動(dòng)態(tài)IP框架

2018-01-22 10:52:43

前端CSS追蹤用戶

2023-12-29 08:17:20

接口類SpringAOP

2020-11-16 13:38:31

PostMessage

2021-07-28 06:10:47

拖拽設(shè)計(jì)器 transmat

2021-09-05 07:55:37

前端Emoji 表情

2021-10-29 07:49:22

Spring事務(wù)管理

2021-10-11 08:08:02

Python異常程序

2012-07-13 11:32:16

網(wǎng)絡(luò)出口

2021-03-02 10:50:23

SpringMVC 參數(shù)JavaWeb

2020-09-14 11:26:54

BinlogCanal數(shù)據(jù)庫

2024-08-02 08:38:20

Controller接口地址

2019-12-05 10:08:39

Python 開發(fā)編程語言

2017-12-07 14:21:57

存儲(chǔ)方式變遷

2022-11-18 07:34:12

Docker項(xiàng)目目錄

2024-05-13 00:47:37

JSON對(duì)象數(shù)據(jù)

2015-04-27 10:51:09

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)