Can you obtain names from parent scope?
Pedro Rodriguez
pedro_rodriguez at club-internet.fr
Sun Jan 19 06:29:30 EST 2003
On Fri, 17 Jan 2003 15:51:35 +0000, Will Sadkin wrote:
> I want to write a function that takes an arbitrary set of objects,
> and prints them in the form "name = <value>." That is, I want to be
> able to say:
>
>>>> a = 'hi!'
>>>> dbgval(a)
> a = hi!
>>>> b = 2
>>>> dbgval(b)
> b = 2
>
> However I can't make this work, because objects don't have any
> intrinsic name, and if I write a function of the form
>>>> def dbgval(*args):
> ...
>
> then dbgval() only knows the arguments objects as belonging to the
> list 'args', and I can't find any way to determine what the names
> were in the parent's local scope when the function was called.
> Is there any way for a function to retrieve this information?
You may have access to parent frame with something like this :
import sys
def show_locals(func):
callerFrame = sys._getframe(1)
locals = eval("locals()", callerFrame.f_globals, callerFrame.f_locals)
print func, locals
def f():
x = 1
def g(y):
w = 2
show_locals("g")
g(x)
show_locals("f")
f()
If you want to write a dbgval function as you describe, you'll need
to pass variable names instead of variable references, in fact you
should pass any string that may be evaluated :
import sys
def dbgval(*names):
callerFrame = sys._getframe(1)
for name in names:
val = eval(name, callerFrame.f_globals, callerFrame.f_locals)
print "%s = %s" %(name, val)
Finally, if for some reason you don't know precisely which names you want
to investigate, but still don't want to use a debugger, you can try the
following code that allow some interactive investigation using the
simplicity of adding a single 'print' like statement :
import sys
def debug():
try:
import readline
except:
pass
try:
callerFrame = sys._getframe(1)
except: # 1.5.2
exceptionType, exceptionValue, exceptionTraceback = sys.exc_info()
exceptionFrame = exceptionTraceback.tb_frame
callerFrame = exceptionFrame.f_back
while 1:
try:
s = raw_input("debug> ")
exec s in callerFrame.f_globals, callerFrame.f_locals
except EOFError:
break
except SystemExit:
raise
except:
traceback.print_exc()
(add 'debug()' at some place, and you'll be able to issue some statements
like 'print a', or 'a.doSomething()')
Pedro
More information about the Python-list
mailing list