Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
209 views
in Technique[技术] by (71.8m points)

python - What is the difference between a stack and a frame?

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Alright, since this appears to be more about what stack frames/call stacks are in general, let's go through this:

def f():
    try:
        g()
    except:
        # WE WILL DO THINGS HERE

def g():
    h()

def h():
    raise Exception('stuff')

#CALL
f()

When we're in h(), there are 4 frames on the call stack.

[top level]
 [f()]
  [g()]
   [h()] #<-- we're here

(if we tried to put more than sys.getrecursionlimit() frames on the stack, we would get a RuntimeError, which is python's version of StackOverflow ;-))

"Outer" refers to everything above us (literally: the direction "up") in the call stack. So in order, g, then f, then the top (module) level. Likewise, "inner" refers to everything downwards in the call stack. If we catch an exception in f(), that traceback object will have references to all of the inner stack frames that were unwound to get us to that point.

def f():
    try:
        g()
    except:
        import inspect
        import sys
        #the third(last) item in sys.exc_info() is the current traceback object
        return inspect.getinnerframes(sys.exc_info()[-1])

This gives:

[(<frame object at 0xaad758>, 'test.py', 3, 'f', ['        g()
'], 0), 
(<frame object at 0x7f5edeb23648>, 'test.py', 10, 'g', ['    h()
'], 0), 
(<frame object at 0x7f5edeabdc50>, 'test.py', 13, 'h', ["    raise Exception('stuff')
"], 0)]

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:

[(<frame object at 0x7f6e996e6a48>, 'test.py', 13, 'h', ["    raise Exception('stuff')
"], 0), 
(<frame object at 0x1bf58b8>, 'test.py', 10, 'g', ['    h()
'], 0), 
(<frame object at 0x7f6e99620240>, 'test.py', 7, 'f', ['        return inspect.getinnerframes(sys.exc_info()[-1])
'], 0), 
(<frame object at 0x7f6e99725438>, 'test.py', 23, '<module>', ['print(inspect.getouterframes(f()[-1][0]))
'], 0)]

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:

[('test.py', 23, '<module>', 'print(traceback.extract_stack(f()[-1][0]))'), 
('test.py', 7, 'f', 'return inspect.getinnerframes(sys.exc_info()[-1])'), 
('test.py', 10, 'g', 'h()'), 
('test.py', 13, 'h', "raise Exception('stuff')")]

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 and traceback.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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...