On 6/11/2009 4:08 AM Kent Johnson said...
On Wed, Jun 10, 2009 at 9:43 PM, Robert Lummis<robert.lum...@gmail.com> wrote:
I want to write a function that I can use for debugging purposes that
prints the values of whatever list of object references it is given as
arguments, without knowing in advance how many object references it
will be called with or what they might be. For example, the call:
show(a,b,c) would output the values of the arguments like this:

   a = 3
   b = 'john'
   c = 'Monday'

while show (x) would output (for example):

   x = 3.14

of course displaying whatever the actual current values are. For a
collection object it would make sense to output just the first few
values.

So within the 'show' function definition I have to somehow get a list
of the literal argument names it was called with and then use the
names as globals to get the values. How do I do that?

I don't know of a straightforward way to do this. You can use
sys._getframe() to get the caller's context but I don't think it will
tell you what variables were used for the call.


Well, kind of.  And somewhat OK for simple variables.

OK.  Let's see what's in _getframe...

>>> import sys

... and a quick function to return _getframe from within a function

>>> def rframe(*args,**kwargs): return sys._getframe()

... now to get one

>>> a,b,c = 1,2,3
>>> xx = rframe(a,b,c)

...a bit of digging and we find these two...

>>> xx.f_locals
{'args': (1, 2, 3), 'kwargs': {}}

>>> xx.f_back.f_code.co_names
('rframe', 'a', 'b', 'c', 'xx')

So, a <cleaned up> first cut at show...

import sys
from pprint import pprint

def show(*args):
    F = sys._getframe()
    argnames = list(F.f_back.f_code.co_names)
    argnames = argnames[argnames.index('show')+1:]
    argvals = F.f_locals['args']
    pprint( zip(argnames,argvals) )

... and some interactive testing...

>>> a,b,c = 1,2,3
>>> show(a,b,c)
[('a', 1), ('b', 2), ('c', 3)]
>>> show(d,e,a,b)
[('d', 4), ('e', 5), ('a', 1), ('b', 2)]
>>> L = [1,2,3]
>>> show(d,e,a,b,L)
[('d', 4), ('e', 5), ('a', 1), ('b', 2), ('L', [1, 2, 3])]

... but watch out for composite objects...

>>> show(d,e,a,b,L[0])
[('d', 4), ('e', 5), ('a', 1), ('b', 2), ('L', 1)]

>>> D = dict([('d', 4), ('e', 5), ('a', 1), ('b', 2), ('L', 1)])
>>> D['L']
1
>>> show(d,e,a,b,D['L'])
[('d', 4), ('e', 5), ('a', 1), ('b', 2), ('D', 1)]

I wouldn't rely on this, but it may be of some use and shows a little of the introspection abilities python provides.

Emile



_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to