Elegant handling of Python Traceback

Source: Internet
Author: User

When we first approached Python, simple exception handling has helped us solve most of the problems, but as we go deeper, we'll find that there are a lot of situations where simple exception handling doesn't solve the problem, and the following code, simple print exceptions, can provide very limited information.

def func1():    raise Exception("--func1 exception--")def main(): try: func1() except Exception as e: print eif __name__ == '__main__': main()

After execution the output is as follows:


By example, we find that ordinary print exceptions have very little information (usually the value of an exception), in which case it is difficult to locate the problem in which block of code, and how this exception occurs. So how exactly do you want to print more detailed information? Let's take a brief introduction.

Sys.exc_info and Traceback Object

The traceback information of a Python program is derived from an object called Traceback object, and this Traceback object is usually obtained by means of a function sys.exc_info (), which takes a first example:

Import Sysdef func1 (): raise nameerror ( "--func1 exception--") def main  (): try:func1 () except Exception Span class= "Hljs-keyword" >as E:exc_type, exc_value, exc_traceback_obj = Sys.exc_info ()  Print  "Exc_type:%s"% exc_type print  "Exc_value:%s"% exc_value print  " Exc_traceback_obj:%s "% Exc_traceback_objif __name__ =  __ Main__ ': Main ()              

After execution the output is as follows:

exc_type: <type 'exceptions.NameError'>exc_value: --func1 exception--exc_traceback_obj: <traceback object at 0x7faddf5d93b0>

As we can see from the above example, Sys.exc_info () Gets the information about the currently processed exception, returns a tuple, the first data of the tuple is the type of the exception (example is the Nameerror type), the second return value is the value of the exception, The third one is the Traceback object we want.

With Traceback object we can print and format traceback information via Traceback module, so let's take a look at the related functions of Traceback module.

Traceback Module

Python's Traceback module provides a complete set of interfaces for extracting, formatting, and printing the stack traces information for Python programs, which we'll look at in more detail in the following examples:

import sysimport tracebackdef func1(): raise NameError("--func1 exception--")def main(): try: func1() except Exception as e: exc_type, exc_value, exc_traceback_obj = sys.exc_info() traceback.print_tb(exc_traceback_obj)if __name__ == '__main__': main()


"<ipython-input-23-52bdf2c9489c>", line 11, in main    func1()File "<ipython-input-23-52bdf2c9489c>", line 6, in func1 raise NameError("--func1 exception--")

Here we can find the print exception information more detailed, below we understand the following PRINT_TB details:

traceback.print_tb(tb[, limit[, file]])
    • TB: This is Traceback object, which we get through sys.exc_info.
    • Limit: This is the stack trace level that is restricted, and if not set or none, all layers of stack trace are printed
    • File: This is the output stream that sets the print, can be a file, or it can be a File-like object such as stdout. If not or none, the output is to Sys.stderr.
Import SysImport Tracebackdef func1(): Raise Nameerror ("--func1 exception--")def Func2(): Func1 ()def  Main(): try:func2 () except Exception as E:exc_type, exc_value, exc_traceback_obj = Sys.exc_info () tr Aceback.print_exception (Exc_type, Exc_value, Exc_traceback_obj, limit=2, file=sys.stdout)if __name__ = = ' __main__ ': Main ()                


Traceback (most recent call last):  "<ipython-input-24-a68061acf52f>", line 13, in main    func2()  File "<ipython-input-24-a68061acf52f>", line 9, in func2    func1()NameError: --func1 exception--

Look at the definition:

traceback.print_exception(etype, value, tb[, limit[, file]])
    • Two more parameters EType and value than PRINT_TB, respectively exception type and exception value, plus TB (Traceback object), exactly the three values returned by Sys.exc_info ()
    • In addition, compared with PRINT_TB, printing information more than the beginning of the "Traceback (most ...)" Information and the exception type and value information for the last line
    • Another difference is that when the exception is SyntaxError, there will be "^" to indicate the location of the syntax error

Print_exc is a simplified version of print_exception, because exception type, both value and Traceback object can be obtained through sys.exc_info (), so Print_exc () automatically executes exc _info () to help get these three parameters, and therefore this function is the most commonly used in our program, because it is simple enough

import sysimport Tracebackdef func1 (): raise nameerror ( "--func1 exception--") def func2  (): Func1 () def main (): try:func2 () except Exception as E:traceback.print_exc (limit= 1, File=sys.stdout) if __name__ =  ' __main__ ': Main ()       

Output (because of limit=1, so only one level is printed out):

Traceback (most recent call last):  "<ipython-input-25-a1f5c73b97c4>", line 13, in main    func2()NameError: --func1 exception--

Defined as follows:

traceback.print_exc([limit[, file]])
    • Only two parameters, simple enough
Import loggingImport SysImport Tracebacklogger = Logging.getlogger ( "Traceback_test") def func1  (): raise nameerror ( "--func1 exception--") def func2 (): Func1 () def main (): try:func2 () except Exception as e:logger.error (Traceback.format_exc (Limit=1, file=sys.stdout)) if __name__ =  ' __main__ ': Main ()                

From this example we can see that sometimes we want a string, for example, we would like to log the exception through logger, this time we need to format_exc, this is the most common function, it is the same as PRINT_EXC usage, It just doesn't print directly but returns a string.

There are some other functions in the Traceback module, but because it is not commonly used, it is not possible to expand, interested students can look at the reference link in the document.

Gets the exception information in the thread

Normally we cannot bring the exception in the multithreading back to the main thread, so we cannot print the exceptions in the threads, and by learning this knowledge, we can make the following modifications to the thread to achieve the purpose of catching the thread exception.
The following example is from a blog post in Weidong and is slightly modified (see the reference link)

Import threadingImport TracebackDefMy_func():Raise Baseexception ("Thread Exception")ClassExceptionthread(Threading. Thread):Def__init__(Self, Group=none, Target=none, Name=none, args=(), Kwargs=none, Verbose=none):"" "Redirect exceptions of thread to an exception handler." "" Threading. Thread.__init__ (self, group, target, name, args, Kwargs, verbose)If KwargsIsNone:kwargs = {} Self._target = target Self._args = args Self._kwargs = Kwargs Self._exc =NoneDefRun(self):TryIf Self._target:self._target ()Except BaseexceptionAs e:Import sys self._exc = Sys.exc_info ()Finally#Avoid a refcycle If the thread is running a function with #an argument that have a member that points to the Threa D. del Self._target, Self._args, Self._kwargs def join(self): threading. Thread.Join (self) if self._exc:msg = "Thread '%s ' threw an exception:%s"% (Self.getname (), self._exc[1]) ne W_exc = Exception (msg) raise new_exc.__class__, New_exc, self._exc[2]t = Exceptionthread (Target=my_func, name =' My_thread ') T.start ()try:t.join ()except:traceback.print_exc ()     

The output is as follows:

Traceback (most recent call last):  "/data/code/testcode/thread_exc.py", line 43, in <module> t.join() File "/data/code/testcode/thread_exc.py", line 23, in run self._target() File "/data/code/testcode/thread_exc.py", line 5, in my_func raise BaseException("thread exception")Exception: Thread 'my_thread' threw an exception: thread exception

This way we get the exception information in the thread.

Reference links

Traceback Official documents

Weidong ' s Blog

Links: www.jianshu.com/p/a8cb5375171a
Source: Pinterest
The copyright of Jane's book is owned by the author, please contact the author in any form for authorization and attribution.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

Tags Index: