Printing literal text of an argument
Mike Meyer
mwm at mired.org
Thu Aug 11 22:13:43 EDT 2005
[Format recovered from top posting]
Jeremy Moles <jeremy at emperorlinux.com> writes:
> On Thu, 2005-08-11 at 14:04 -0700, Rex Eastbourne wrote:
>> Hi all,
>>
>> I've written the following simple macro called debug(aname, avalue)
>> that prints out the name of an expression and its value:
>>
>> def debug(aname, avalue):
>> print aname, 'is':
>> pprint.pprint(avalue)
>>
>> An example call is:
>>
>> debug('compose(f1,f2)', compose(f1,f2))
>>
>> Writing the exact same thing twice (one in quotes and the other not)
>> sets off an alarm in my head. Is there a way to make this function take
>> only one argument, and use both its value and its literal form? On a
>> slightly different topic, is it also possible to make the macro print
>> the line number where the function was first called?
> def debug(s):
> print "s"
> exec(s)
Um, no. First, I'm pretty sure you mean "print s" for the print
statement. The one you have just prints a single s. Second, exec is a
statement, not a function. The correct syntax is "exec s". The one you
used works, because an expression in parenthesies evaluates to the
value of the expression. Finally, doing an "exec s" doesn't display a
value - you need to print the results of the exec, which you can't
do. You want to use an eval here, not an exec. Eval is a function, and
returns a value. It's limited to expressions. Which will meet Rex's
stated requirements.
Of course, all this is moot because the eval (exec) happens in a
different context than the call, so the results can be radically
different than what you expect:
>>> def debug(s):
... print s
... print eval(s)
...
>>> def foo():
... x = 3
... debug("x")
...
>>> foo()
x
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in foo
File "<stdin>", line 3, in debug
File "<string>", line 1, in ?
NameError: name 'x' is not defined
>>>
See what I mean?
You really need to pass the context to debug for it to get the right
thing:
>>> def debug(x, glob, loc):
... print x
... print eval(x, glob, loc)
...
>>> def foo():
... x = 3
... debug("x", globals(), locals())
...
>>> foo()
x
3
>>>
You can figure out the locals via introspection (see the help for the
inspect module for more details). I'm not sure if there's a similar
way to figure out what the globals were at the point that debug is
called.
<mike
--
Mike Meyer <mwm at mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
More information about the Python-list
mailing list