Augmentez vos connaissances! Les informations sur les exceptions de Python peuvent également être affichées comme ceci

王林
Libérer: 2023-04-11 16:40:03
avant
1775 Les gens l'ont consulté

Augmentez vos connaissances! Les informations sur les exceptions de Python peuvent également être affichées comme ceci

Introduction

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é.

Exception Hooks

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
Copier après la connexion

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
Copier après la connexion

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'}
Copier après la connexion

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.

Hooks d'exception personnalisés

  1. Nous pouvons également stocker automatiquement les informations d'exception dans un fichier et les afficher lors du débogage du code ultérieurement :
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")
Copier après la connexion
  1. Les informations d'exception seront stockées dans stderr par défaut, si vous souhaitez modifier le Position de stockage, vous pouvez faire ceci :
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
Copier après la connexion
  1. Nous pouvons également définir la couleur d'une certaine partie du message d'invite :
# 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}")
Copier après la connexion

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.

  • Afficher les variables locales de chaque frame [1]
  • Trouver les variables référencées dans la ligne où l'exception se produit [2]

Hooks d'exception dans les bibliothèques tierces

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.

  1. Tout d'abord, mon préféré est Rich, qui peut être installé directement avec pip puis importé pour être utilisé. Si vous ne souhaitez l'utiliser que dans un exemple, vous pouvez faire ceci : 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
Copier après la connexion

Augmentez vos connaissances! Les informations sur les exceptions de Python peuvent également être affichées comme ceci

  1. better_exceptions sont également très populaires, nous devons d'abord définir la variable d'environnement BETTER_EXCEPTIONS=1, puis installez-le avec pip. De plus, si votre variable TERM n'est pas xterm, définissez SUPPORTS_COLOR sur True.
# 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
Copier après la connexion

Augmentez vos connaissances! Les informations sur les exceptions de Python peuvent également être affichées comme ceci

  1. La bibliothèque la plus pratique à utiliser est Pretty_errors, il suffit de l'importer :
# 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()
Copier après la connexion

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]

Augmentez vos connaissances! Les informations sur les exceptions de Python peuvent également être affichées comme ceci

  1. Module ultratb d'IPython
# 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()
Copier après la connexion

Augmentez vos connaissances! Les informations sur les exceptions de Python peuvent également être affichées comme ceci

  1. stackprinter库
# https://github.com/cknd/stackprinter
# pip install stackprinter
import stackprinter
stackprinter.set_excepthook(style='darkbg2')
do_stuff()
Copier après la connexion

Augmentez vos connaissances! Les informations sur les exceptions de Python peuvent également être affichées comme ceci

结论

本文我们学习了如何自定义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!

Étiquettes associées:
source:51cto.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!