How can you programmatically inspect the stack trace of an exception in Python?

前端 未结 5 1378
一个人的身影
一个人的身影 2021-02-02 12:19

When an exception occurs in Python, can you inspect the stack? Can you determine its depth? I\'ve looked at the traceback module, but I can\'t figure out how to use it.

<
相关标签:
5条回答
  • 2021-02-02 13:01

    I like the traceback module.

    You can get a traceback object using sys.exc_info(). Then you can use that object to get a list preprocessed list of traceback entries using traceback.extract_tb(). Then you can get a readable list using traceback.format_list() as follows:

    import sys
    import traceback, inspect
    
    try:
        f = open("nonExistant file",'r')
    except:
        (exc_type, exc_value, exc_traceback) = sys.exc_info()
        #print exception type
        print exc_type
        tb_list = traceback.extract_tb(sys.exc_info()[2])
        tb_list = traceback.format_list(tb_list)
        for elt in tb_list:
            print elt
            #Do any processing you need here.
    

    See the sys Module: http://docs.python.org/library/sys.html

    and the traceback Module: http://docs.python.org/library/traceback.html

    0 讨论(0)
  • 2021-02-02 13:17

    In addition to AndiDog's answer about inspect, note that pdb lets you navigate up and down the stack, inspecting locals and such things. The source in the standard library pdb.py could be helpful to you in learning how to do such things.

    0 讨论(0)
  • 2021-02-02 13:18

    You can use the inspect module which has some utility functions for tracing. Have a look at the overview of properties of the frame objects.

    0 讨论(0)
  • 2021-02-02 13:20

    You define such a function (doc here):

    def raiseErr():
       for f in inspect.stack(): print '-', inspect.getframeinfo(f[0])
    

    and call it from your modules so:

    raiseErr()
    

    The function raiseErr will print info about the place you called it.

    More elaborate, you can do so:

    import inspect, traceback
    A = [inspect.getframeinfo(f[0]) for f in inspect.stack()]
    print "traceback structure fields:", filter(lambda s: s[0] != '_', dir(A[0]))
    print A[0].filename, A[0].lineno
    for f in inspect.stack():
        F = inspect.getframeinfo(f[0])
        print '-', F.filename, F.lineno, '\t', F.code_context[0].strip()
    

    Other possibility is to define this function:

    def tr():
        print '* - '*10,
        print sys._getframe(1).f_code.co_name
    

    And call it in the place where you want the trace. If you want all the trace, make an iterator from 1 up in _getframe(1).

    0 讨论(0)
  • 2021-02-02 13:22

    traceback is enough - and I suppose that documentation describes it rather well. Simplified example:

    import sys
    import traceback
    
    try:
        eval('a')
    except NameError:
        traceback.print_exc(file=sys.stdout)
    
    0 讨论(0)
提交回复
热议问题