Under what situations would I want to use one over the other?
What is the difference between:
>>> import inspect
>>> print(inspect.getouterframes(inspect.currentframe()))
[(<frame object at 0x8fc262c>, '<stdin>', 1, '<module>', None, None)]
And:
>>> import traceback
>>> traceback.extract_stack()
[('<stdin>', 1, '<module>', None)]
Update:
Another:
>>> import sys
>>> print(sys._getframe().f_trace,sys._getframe().f_code)
(None, <code object <module> at 0x8682a88, file "<stdin>", line 1>)
I do not understand the nuances here:
- Stack Frame
- Frame Object
- Stack Trace
update 2, a bit of time since the question was asked, but very relevant
Alright, since this appears to be more about what stack frames/call stacks are in general, let's go through this:
When we're in
h()
, there are 4 frames on the call stack.(if we tried to put more than
sys.getrecursionlimit()
frames on the stack, we would get aRuntimeError
, which is python's version ofStackOverflow
;-))"Outer" refers to everything above us (literally: the direction "up") in the call stack. So in order,
g
, thenf
, then the top (module) level. Likewise, "inner" refers to everything downwards in the call stack. If we catch an exception inf()
, that traceback object will have references to all of the inner stack frames that were unwound to get us to that point.This gives:
As expected, the three inner frames f, g, and h. Now, we can take that last frame object (the one from
h()
) and ask for its outer frames:So, there you go, that's all that's going on: we're simply navigating the call stack. For comparison, here's what
traceback.extract_stack(f()[-1][0])
gives:Notice the inverted order here compared to
getouterframes
, and the reduced output. In fact, if you squint your eyes, this basically looks like a regular traceback (and hey, it is, with just a little bit more formatting).Summing up: both
inspect.getouterframes
andtraceback.extract_stack
contain all the information to reproduce what you generally see in your everyday traceback;extract_stack
just removes the references to the stack frames, since it is very common to no longer need them once you get to the point of formatting your stack trace from-a-given-frame-outwards.The documentation for the
inspect
module says:The documentation for the
traceback
module says:Hence the difference is that the frame record also includes the frame object and some lines of context, while the traceback only includes the text of the individual lines in the call stack (i.e., the calls that led to the
extract_stack
call).You would use the stack from
traceback
if you just want to print a traceback. As the documentation suggests, this is information processed for showing to the user. You would need access to the frame object frominspect
if you wanted to actually do anything with the call stack (e.g., read variables from calling frames).