inspect.stack() and frame

Félix-Antoine Fortin felix.antoine.fortin at gmail.com
Thu Mar 11 19:03:07 EST 2010


On Mar 11, 6:22 pm, "Alf P. Steinbach" <al... at start.no> wrote:
> * F lix-Antoine Fortin:
>
> > Given this code :
> > # Experience with frame
> > import sys
> > import inspect
>
> > def foo():
> >     stack = inspect.stack()
> >     print "foo frame : " + str(hex(id(sys._getframe())))
>
> hex returns a string. applying str is therefore redundant.
>

My bad.

>
>
>
>
> > def foo2():
> >     inspect.stack()
> >     print "foo2 frame : " + str(hex(id(sys._getframe())))
>
> > def bar():
> >     print "bar frame : " + str(hex(id(sys._getframe())))
>
> > foo()
> > foo()
>
> > foo2()
> > foo2()
>
> > bar()
> > bar()
>
> > Output example :
> > foo frame : 0x84d2c0
> > foo frame : 0x844bf0
> > foo2 frame : 0x898c90
> > foo2 frame : 0x898c90
> > bar frame : 0x898f70
> > bar frame : 0x898f70
>
> > Why are the ids (address) of the frame for each foo call not the same?
>
> You're dealing with Python objects. You're not dealing with the computer's
> machine stack. Whether you get the same id for two objects whose lifetimes don't
> overlap depends on the implementation's memory and id allocation strategy.
>

Okay, I thought I got that when I read the id documentation, but now I
get it.
So the only to compare two ids, is by making sure their lifetimes
overlap. In
this case, instead of keeping the ids, I have to keep a reference on
the frame
to make sure it is still alive when I will compare it with a second
one.

Thanks!

> > Or why the call to "stack = inspect.stack()" change the address of the
> > frame?
>
> Does it?
>

Yeah it does... I always get N different id when I run foo() N times
in a row.
Actually, what you said about lifetime applies here too. Here is
another quick
snippet :

import sys
import inspect

def foo():
    stack = inspect.stack()
    return sys._getframe()

def foo2():
    stack = inspect.stack()
    del stack
    return sys._getframe()

def bar():
        inspect.stack()
        return sys._getframe()

frame_foo = foo()
frame_foo2 = foo2()
frame_bar = bar()

print sys.getrefcount(frame_foo)
print sys.getrefcount(frame_foo2)
print sys.getrefcount(frame_bar)

Output :
3
2
2

So it seems that there is one more reference to the foo frame because
only because of "stack = inspect.stack()", so its lifetime isn't done
contrary to foo2 and bar frame, and the frame id of a foo frame is
different for each call.

Now, what is keeping a reference on foo frame?

Thanks Alf,

Felix




More information about the Python-list mailing list