Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Function that knows its argument's variable name

4 views
Skip to first unread message

Helge Stenström

unread,
Mar 14, 2010, 7:58:07 AM3/14/10
to
I want to write function that prints a value of a variable, for
debugging. Like:

with

myVariable = "parrot"
otherVariable = "dead"

probe(myVariable)
probe(otherVariable)

instead of the longer

print "myVariable = ", myVariable
print "otherVariable = ", otherVariable

Is that even possible?

The function would look like

def probe(var):
nameOfVar = someMagic(var)
print nameOfVar, " = ", var

but can someMagic(var) find the variable name? Is that possible?

Gary Herron

unread,
Mar 14, 2010, 12:45:51 PM3/14/10
to pytho...@python.org

That question really doesn't quite make sense. Consider all the
ways such a function can be called:
someMagic(42)
someMagic(40+2)
someMagic(f(123))
someMagic(*argTuple)
someMagic(**kwDict)
someMagic(array[42])
None of which have a variable name associated with the argument.

Yet, the answer to your question is not quite absolutely "no". Python
has lots of introspection capabilities, including, perhaps, getting at
and parsing the original code to find the call. But there's nothing
direct for what you want.

Gary Herron



Gregory Ewing

unread,
Mar 16, 2010, 7:32:40 PM3/16/10
to
Helge Stenström wrote:

> I want to write function that prints a value of a variable, for
> debugging. Like:
>

> myVariable = "parrot"
> otherVariable = "dead"
>
> probe(myVariable)
> probe(otherVariable)

Not exactly, but you can come close with a little hackery.

import sys

def print_var(name):
print name, "=", sys._getframe(1).f_locals[name]

def f():
fred = 42
mary = "christmas"
print_var("fred")
print_var("mary")

f()

--
Greg

Phlip

unread,
Mar 16, 2010, 7:40:46 PM3/16/10
to
> Yet, the answer to your question is not quite absolutely "no".  Python
> has lots of introspection capabilities, including, perhaps, getting at
> and parsing the original code to find the call.    But there's nothing
> direct for what you want.
>
> Gary Herron

Below my sig is one shot at it; which requires a lambda: for other
reasons. It's an assertion used with Django models.

You can search for the name of your trace method, instead of lambda,
using this brute-force technique.

And here's a nice thread on Greg's technique, from a very short time
ago:

http://groups.google.com/group/comp.lang.python/msg/03dd85ce009044e9

--
Phlip
http://penbird.tumblr.com/

def assert_model_changes(self, mod, item, frum, too, lamb):
source = open(lamb.func_code.co_filename, 'r').readlines()
[lamb.func_code.co_firstlineno - 1]
source = source.replace('lambda:', '').strip()
model = str(mod.__class__).replace("'>", '').split('.')[-1]

should = '%s.%s should equal `%s` before your activation line,
`%s`' % \
(model, item, frum, source)

self.assertEqual(frum, mod.__dict__[item], should)
lamb()
mod = mod.__class__.objects.get(pk=mod.pk)

should = '%s.%s should equal `%s` after your activation line, `
%s`' % \
(model, item, too, source)

self.assertEqual(too, mod.__dict__[item], should)
return mod

Tino Wildenhain

unread,
Mar 17, 2010, 2:30:36 AM3/17/10
to Helge Stenström, pytho...@python.org
Hi,

apart from very hackery, why don't you just use:

def probe(**vars):
for varname,value in vars.items():
print "%s = %r" % (varname,value)

and call it like that:

probe(myvar="foo")
probe(othervar="bar")

or even

probe(myvar=myvar) (if myvar was assigned before)

please note introspective approaches have a very narrow field
where they can work - as already shown in other posts: you can have
values w/o names and also more then one name to a value (or object).

Regards
Tino Wildenhain

Helge Stenström

unread,
Mar 17, 2010, 9:20:42 AM3/17/10
to
Thank you to all who answered. Inspection is apparently possible, but
too complex for me.
Greg's solution does what I want, inserting "" is no problem.

/Helge

0 new messages