[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)"

9
>>> d = 3
>>> eval("fvar(d)"

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