Dans le développement quotidien, la plupart de notre temps est consacré à la lecture des informations du module de traçabilité et au débogage du code. Dans cet article, nous améliorerons le module de traçabilité pour rendre les informations d'invite plus concises et précises.
Sur la base de cet objectif, nous personnaliserons les Exception Hooks (hooks de gestion des exceptions) pour supprimer les informations redondantes dans le traçage, ne laissant que le contenu requis pour résoudre l'erreur. De plus, je présenterai également quelques bibliothèques tierces utiles, et vous pourrez directement y utiliser les Exception Hooks pour simplifier le module de traçabilité.
Si les informations d'exception du programme ne sont pas capturées par try/catch, l'interpréteur python appellera la fonction sys.saufhook(), qui recevra 3 paramètres : type, valeur, traceback. Cette fonction est également appelée Exception Hook et affichera les informations d'exception du programme.
Jetons un coup d'œil à l'exemple suivant :
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
Dans cet exemple, nous pouvons obtenir l'emplacement où les informations d'exception apparaissent à partir de l'objet traceback (tb). Les informations d'emplacement incluent : le nom du fichier (f_code.co_filename), nom de la fonction/du module (f_code.co_name) et numéro de ligne (tb_lineno). De plus, nous pouvons utiliser les variables exc_type et exc_value pour obtenir le contenu des informations d'exception.
Lorsque nous appelons une fonction qui génère une erreur, exception_hook affichera le contenu suivant :
def do_stuff(): # 写一段会产生异常的代码 raise ValueError("Some error message") do_stuff() # Traceback: # File /home/some/path/exception_hooks.py line 22, in <module> # ValueError, Message: Some error message
L'exemple ci-dessus fournit une partie des informations sur l'exception, mais pour obtenir toutes les informations nécessaires pour déboguer le code, et savoir quand et quand l'exception se produit Emplacement, nous devons également nous plonger dans l'objet traceback :
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'}
Comme le montre l'exemple ci-dessus, l'objet traceback (tb) est essentiellement une liste chaînée - stockant toutes les exceptions qui se produisent. Par conséquent, vous pouvez utiliser tb_next pour parcourir tb et imprimer les informations de chaque exception. Sur cette base, vous pouvez également utiliser l'attribut tb_frame.f_locals pour afficher des variables sur la console, ce qui facilite le débogage du code.
Il est possible d'utiliser l'objet traceback pour générer des informations d'exception, mais c'est plus gênant. De plus, les informations de sortie sont moins lisibles. Une approche plus pratique consiste à utiliser le module de traçabilité, qui possède de nombreuses fonctions auxiliaires intégrées pour extraire les informations sur les exceptions.
Maintenant, nous avons introduit les connaissances de base des Exception Hooks. Ensuite, nous pouvons personnaliser un hook d'exception et ajouter quelques fonctionnalités pratiques.
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")
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
# 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}")
En plus des exemples introduits ci-dessus, vous pouvez également afficher les variables locales de chaque image , ou recherchez la ligne où l'exception se produit dans les variables référencées dans . Ces hooks d'exception sont déjà très matures. Par rapport aux hooks d'exception personnalisés, je vous suggère de lire le code source d'autres développeurs et d'apprendre leurs idées de conception.
La personnalisation d'un hook d'exception est très intéressant, mais de nombreuses bibliothèques tierces ont déjà implémenté cette fonction. Plutôt que de réinventer la roue, regardez d’autres outils formidables.
# 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
# https://github.com/Qix-/better-exceptions # pip install better_exceptions # export BETTER_EXCEPTIONS=1 import better_exceptions better_exceptions.MAX_LENGTH = None # 检查你的 TERM 变量是否被设置为 `xterm`, 如果没有执行以下操作 # See issue: https://github.com/Qix-/better-exceptions/issues/8 better_exceptions.SUPPORTS_COLOR = True better_exceptions.hook() do_stuff()# Raises ValueError
# https://github.com/onelivesleft/PrettyErrors/ # pip install pretty_errors import pretty_errors # 如果你对默认配置满意的话,则无需修改 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()
En plus de l'importation directe, le code ci-dessus montre également certaines configurations facultatives de cette bibliothèque. Plus de configurations peuvent être consultées ici : Configuration [3]
# 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()
# https://github.com/cknd/stackprinter # pip install stackprinter import stackprinter stackprinter.set_excepthook(style='darkbg2') do_stuff()
本文我们学习了如何自定义Exception Hooks,但我更推荐使用第三方库。你可以在本文介绍的第三方库中任选一个喜欢的,用到项目中。需要注意的是使用自定义Exception Hooks可能会丢失某些关键信息,例如:本文中的某些例子中,输出中缺少文件路径,在远程调试代码这无疑很不方便,因此,需要谨慎使用。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!