Get last function's call arguments from traceback?

后端 未结 3 1496
滥情空心
滥情空心 2021-01-07 04:50

Can I get the parameters of the last function called in traceback? How?

I want to make a catcher for standard errors to make readable code, yet provide detailed info

相关标签:
3条回答
  • 2021-01-07 05:20

    Here is an example of such function and some problems that you can't get around:

    import sys
    
    def get_params(tb):
        while tb.tb_next:
            tb = tb.tb_next
        frame = tb.tb_frame
        code = frame.f_code
        argcount = code.co_argcount
        if code.co_flags & 4: # *args
            argcount += 1
        if code.co_flags & 8: # **kwargs
            argcount += 1
        names = code.co_varnames[:argcount]
        params = {}
        for name in names:
            params[name] = frame.f_locals.get(name, '<deleted>')
        return params
    
    
    def f(a, b=2, c=3, *d, **e):
        del c
        c = 4
        e['g'] = 6
        assert False
    
    try:
        f(1, f=5)
    except:
        print get_params(sys.exc_info()[2])
    

    The output is:

    {'a': 1, 'c': 4, 'b': 2, 'e': {'g': 6, 'f': 5}, 'd': ()}
    

    I didn't used inspect.getinnerframes() to show another way to get needed frame. Although it simplifies a bit, it also do some extra work that is not needed for you while being relatively slow (inspect.getinnerframes() reads source file for every module in traceback; this is not important for one debugging call, but could be an issue in other cases).

    0 讨论(0)
  • 2021-01-07 05:21

    The problem with using a decorator for what you're trying to achieve is that the frame the exception handler gets is do_your_job()s, not os.listdir()s, os.makedirs()s or os.chown()s. So the information you'll be printing out is the arguments to do_your_job(). In order to get the behavior I think you intend, you would have to decorate all the library functions you're calling.

    0 讨论(0)
  • 2021-01-07 05:42

    For such inspection tasks, always think first of module inspect in the standard library. Here, inspect.getargvalues gives you the argument values given a frame, and inspect.getinnerframes gives you the frames of interest from a traceback object.

    0 讨论(0)
提交回复
热议问题