[Tutor] How do I do this in python?
Emile van Sebille
emile at fenx.com
Thu Jun 11 17:37:38 CEST 2009
On 6/11/2009 4:08 AM Kent Johnson said...
> On Wed, Jun 10, 2009 at 9:43 PM, Robert Lummis<robert.lummis at 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
More information about the Tutor
mailing list