The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

import-bot (20211) [Avatar] Offline
#1
[Originally posted by lsloan]

How can I use a function assigned to a variable with
"%" string formatting when I have a dictionary on
the right-hand side?

Maybe an example will help me explain what I'm
trying to do. I had hoped that this code:

def square(n): return n * n

fvar = square

print "%(fvar)s
" % vars()
print "%(fvar(3))s
" % vars()

Would simply print "9". Obviously, I don't have
the correct syntax here, because Python complains,
"KeyError: fvar(3)". What's the correct way to do
this?

I'm trying to make up a simple templating system
here. The string will come from a file and the
dictionary will contain values and references to
functions. I would really love to nest the variables
in the string, too, like:

"%(fvar(%(someVar)d))d"

I'm probably hoping for too much.

Since this is my first post to this forum, I'd like
to let the "Quick Python" authors know that I'm
enjoying their book. I especially like the fact that
I could find "%" in the index, which I've been unable
to do with the documentation that came with Python.
(But I did wonder why "vars()" wasn't covered in the
book.)
import-bot (20211) [Avatar] Offline
#2
Re: using function in dict-based "%" string formatting?
[Originally posted by daryl harms]

> How can I use a function assigned to a variable with
> "%" string formatting when I have a dictionary on
> the right-hand side?
>
> Maybe an example will help me explain what I'm
> trying to do. I had hoped that this code:
>
> def square(n): return n * n
>
> fvar = square
>
> print "%(fvar)s
> " % vars()
> print "%(fvar(3))s
> " % vars()
>
> Would simply print "9". Obviously, I don't have
> the correct syntax here, because Python complains,
> "KeyError: fvar(3)". What's the correct way to do
> this?
>
> I'm trying to make up a simple templating system
> here. The string will come from a file and the
> dictionary will contain values and references to
> functions. I would really love to nest the variables
> in the string, too, like:
>
> "%(fvar(%(someVar)d))d"
>
> I'm probably hoping for too much.
>
> Since this is my first post to this forum, I'd like
> to let the "Quick Python" authors know that I'm
> enjoying their book. I especially like the fact that
> I could find "%" in the index, which I've been unable
> to do with the documentation that came with Python.
> (But I did wonder why "vars()" wasn't covered in the
> book.)

Thanks for pointing this out. We were generally using dir() in most examples
in the book as it has very similar functionality.

But, vars() should definitely have at least been mentioned in the reference
and be in the index. The dictionary it returns can be used on the right hand
side of the % operator as you are doing.

>>> def square(n): return n * n

>>> fvar = square
>>> vars()
{'__doc__': None, 'square': <function square at 00B589FC>, 'fvar': <function>
square at 00B589FC>, '__name__': '__main__', '__builtins__': <module>
'__builtin__' (built-in)>}
>>> print "%(fvar)s" % vars()
<function square at 00B589FC>


>>> print "%(fvar(3))s" % vars()
Traceback (innermost last):
File "<pyshell#17>", line 1, in ?
print "%(fvar(3))s" % vars()
KeyError: fvar(3)

The problem you are experiencing with the last line above is the fact that a
named parameter must be a key in the dictionary on the right of the %
operator. In this case "fvar" is a key but fvar(3) is not.

I don't believe you will be able to get the functionality you are after out of
using the % operator alone. However, for what you are trying to do I believe
the built-in eval functions might prove useful.

eval will evaluate a string as python code:
>>> eval("fvar(3)"smilie
9
>>> d = 3
>>> eval("fvar(d)"smilie
9

You can also generate the string using the % and + operators

Another function that you might be able to use is apply.
apply will call a function along with a list of given arguments:
>>> apply(fvar,[3])
9
>>> apply(fvar,[d])
9

I'm not sure if these will help you get what you want. If after playing around
with them a while you are still having troubles, don't hesitate to post a
followup (or email me if you prefer) with more details about what you are
trying to do.

Daryl