Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Tingkatkan pengetahuan anda! Maklumat pengecualian Python juga boleh dipaparkan seperti ini

Tingkatkan pengetahuan anda! Maklumat pengecualian Python juga boleh dipaparkan seperti ini

王林
王林ke hadapan
2023-04-11 16:40:031758semak imbas

Tingkatkan pengetahuan anda! Maklumat pengecualian Python juga boleh dipaparkan seperti ini

Pengenalan

Dalam pembangunan harian, kebanyakan masa kita dihabiskan untuk membaca maklumat modul surih balik dan kod nyahpepijat. Dalam artikel ini, kami akan menambah baik modul jejak balik untuk menjadikan maklumat segera lebih ringkas dan tepat.

Berdasarkan tujuan ini, kami akan menyesuaikan Cangkuk Pengecualian (cangkuk pengendalian pengecualian) untuk mengalih keluar maklumat berlebihan dalam surih, hanya meninggalkan kandungan yang diperlukan untuk menyelesaikan ralat. Selain itu, saya juga akan memperkenalkan beberapa perpustakaan pihak ketiga yang berguna, dan anda boleh terus menggunakan Cangkuk Pengecualian di dalamnya untuk memudahkan modul jejak balik.

Cangkuk Pengecualian

Jika maklumat pengecualian program tidak ditangkap melalui try/catch, penterjemah python akan memanggil fungsi sys.excepthook(), yang akan menerima 3 parameter, masing-masing: jenis, nilai, jejak balik. Fungsi ini juga dipanggil Exception Hook dan akan mengeluarkan maklumat pengecualian program.

Mari kita lihat contoh berikut:

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

Dalam contoh ini, kita boleh mendapatkan maklumat lokasi dan lokasi daripada objek jejak balik (tb). nama (f_code.co_filename), nama fungsi/modul (f_code.co_name), dan nombor baris (tb_lineno). Selain itu, kita boleh menggunakan pembolehubah exc_type dan exc_value untuk mendapatkan kandungan maklumat pengecualian.

Apabila kita memanggil fungsi yang menghasilkan ralat, exception_hook akan mengeluarkan kandungan berikut:

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

Contoh di atas menyediakan sebahagian daripada maklumat pengecualian, tetapi untuk mendapatkan kod penyahpepijatan, Semua maklumat yang diperlukan, dan untuk mengetahui masa dan lokasi pengecualian, kita juga perlu mengkaji objek jejak balik secara mendalam:

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'}

Seperti yang dapat dilihat daripada contoh di atas, objek jejak balik (tb) pada asasnya ialah senarai terpaut - Menyimpan semua pengecualian yang berlaku. Oleh itu, anda boleh menggunakan tb_next untuk melintasi tb dan mencetak maklumat setiap pengecualian. Atas dasar ini, anda juga boleh menggunakan atribut tb_frame.f_locals kepada pembolehubah output ke konsol, yang membantu menyahpepijat kod.

Adalah boleh menggunakan objek surih untuk mengeluarkan maklumat pengecualian, tetapi ia lebih menyusahkan Selain itu, maklumat output kurang boleh dibaca. Pendekatan yang lebih mudah ialah menggunakan modul jejak balik, yang mempunyai banyak fungsi tambahan terbina dalam untuk mengekstrak maklumat pengecualian.

Kini kami telah memperkenalkan pengetahuan asas Cangkuk Pengecualian Seterusnya, kami boleh menyesuaikan cangkuk pengecualian dan menambah beberapa ciri praktikal.

Cangkuk Pengecualian Tersuai

  1. Kami juga boleh menyimpan maklumat pengecualian secara automatik dalam fail dan melihatnya kemudian apabila menyahpepijat kod:
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. Maklumat pengecualian akan disimpan dalam stderr secara lalai Jika anda ingin menukar lokasi storan, anda boleh melakukan ini:
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. Kami. juga boleh memberi gesaan Tetapkan warna bahagian tertentu maklumat:
# 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}")

Selain contoh yang diperkenalkan di atas, anda juga boleh mengeluarkan pembolehubah setempat bagi setiap bingkai atau cari pembolehubah dirujuk dalam baris di mana pengecualian berlaku. Cangkuk Pengecualian ini sudah sangat matang Berbanding dengan cangkuk Pengecualian tersuai, saya cadangkan anda membaca kod sumber pembangun lain dan mempelajari idea reka bentuk mereka.

  • Keluarkan pembolehubah setempat bagi setiap bingkai [1]
  • Cari pembolehubah yang dirujuk dalam baris di mana pengecualian berlaku [2]

Cangkuk Pengecualian dalam perpustakaan pihak ketiga

Memang menarik untuk menyesuaikan Cangkuk Pengecualian, tetapi banyak perpustakaan pihak ketiga telah melaksanakan fungsi ini. Daripada mencipta semula roda, lihat alat hebat yang lain.

  1. Pertama sekali, kegemaran peribadi saya ialah Kaya, yang boleh dipasang terus dengan pip dan kemudian diimport untuk digunakan. Jika anda hanya mahu menggunakannya dalam satu contoh, anda boleh melakukan ini: 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

Tingkatkan pengetahuan anda! Maklumat pengecualian Python juga boleh dipaparkan seperti ini

  1. better_exceptions juga popular , Kita perlu menetapkan pembolehubah persekitaran BETTER_EXCEPTIONS=1 dahulu, dan kemudian memasangnya dengan pip. Selain itu, jika pembolehubah TERM anda bukan xterm, tetapkan SUPPORTS_COLOR kepada Benar.
# 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

Tingkatkan pengetahuan anda! Maklumat pengecualian Python juga boleh dipaparkan seperti ini

  1. Pustaka yang paling mudah digunakan ialah pretty_errors, hanya importnya:
# 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()

Dalam selain import langsung, kod di atas juga menunjukkan beberapa konfigurasi pilihan perpustakaan. Lebih banyak konfigurasi boleh dilihat di sini: Konfigurasi [3]

Tingkatkan pengetahuan anda! Maklumat pengecualian Python juga boleh dipaparkan seperti ini

  1. Modul ultratb 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()

Tingkatkan pengetahuan anda! Maklumat pengecualian Python juga boleh dipaparkan seperti ini

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

Tingkatkan pengetahuan anda! Maklumat pengecualian Python juga boleh dipaparkan seperti ini

结论

本文我们学习了如何自定义Exception Hooks,但我更推荐使用第三方库。你可以在本文介绍的第三方库中任选一个喜欢的,用到项目中。需要注意的是使用自定义Exception Hooks可能会丢失某些关键信息,例如:本文中的某些例子中,输出中缺少文件路径,在远程调试代码这无疑很不方便,因此,需要谨慎使用。

Atas ialah kandungan terperinci Tingkatkan pengetahuan anda! Maklumat pengecualian Python juga boleh dipaparkan seperti ini. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:51cto.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam