469,927 Members | 1,910 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,927 developers. It's quick & easy.

Printing literal text of an argument

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?

Thanks,

Rex

Aug 11 '05 #1
6 1273
def debug(s):
print "s"
exec(s)

The line thing i'm not so sure about. Er. Hmmm.

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?

Thanks,

Rex


Aug 11 '05 #2
[Format recovered from top posting]

Jeremy Moles <je****@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 <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Aug 12 '05 #3
Rex Eastbourne wrote:
def debug(aname, avalue):
print aname, 'is':
pprint.pprint(avalue)

use eval:

def debug(s):
print s, 'is'
pprint.pprint(eval(s))

(it does mean the arg is a string not code......)
On a
slightly different topic, is it also possible to make the macro print
the line number where the function was first called?


You can raise and catch an exception then walk up the call stack:

import sys

def debug(s):
print s, 'is'
pprint.pprint(eval(s))

try:
raise ""
except:
tb = sys.exc_info()[2]
# Find the calling frame
frame = tb.tb_frame.f_back
print "Called from line", frame.f_lineno

See the language reference manual sec 3.2 "Standard Type Hierarchy".
Aug 12 '05 #4
Thanks. I adapted it a bit:

def debug(foo):
print foo, 'is:'
exec('pprint.pprint(' + foo + ')')

But I'm getting "NameError: name 'foo' is not defined," since foo is
not defined in this scope. (The function works beautifully when I'm
dealing with global variables, which is very rarely).

Any way around this?

Rex

Aug 12 '05 #5
Rex Eastbourne wrote:
Thanks. I adapted it a bit:

def debug(foo):
print foo, 'is:'
exec('pprint.pprint(' + foo + ')')

But I'm getting "NameError: name 'foo' is not defined," since foo is
not defined in this scope. (The function works beautifully when I'm
dealing with global variables, which is very rarely).

Any way around this?


Eh, yes, but it's getting uglier...

def debug(foo):
print foo, 'is:'
frame = sys._getframe(-1)
exec 'pprint.pprint(%s)' % foo, frame.f_globals, frame.f_locals

Untested.

Reinhold
Aug 13 '05 #6
Rex -

If what you are looking for is a monitor of calls to a certain
function, check out this decorator example from the Python Wiki:

http://wiki.python.org/moin/PythonDe...fec0ff4b3653f4

This will allow you to very quickly turn on/off debugging for a given
routine, with no changes required in the calling code.

-- Paul

Aug 13 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

9 posts views Thread by Steven T. Hatton | last post: by
7 posts views Thread by al | last post: by
10 posts views Thread by Jeff B. | last post: by
reply views Thread by Nigel | last post: by
13 posts views Thread by stephen | last post: by
4 posts views Thread by Mukesh_Singh_Nick | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.