Outputting strings in html

Skip Montanaro skip at pobox.com
Tue Dec 3 14:20:33 EST 2002


    >> print """
    >> <html><head><title>hello</title></head>
    >> <body bgcolor=color>
    >> .....
    >> """
    >> but I can't get the string to be displayed?

    Stephan> use '<body bgcolor="%s">' % color

    Stephan> This just works like printf in C.

In some cases, even better than printf-style is to use named substitution.
If you have a lot of % formatting to do in a single string, matching up all
the %s's with all the variables can be cumbersome.  This simple example
doesn't do the technique justice, but is analogous to the above example:

    '<body bgcolor="%(color)s">' % locals()

where color is a local variable and locals() returns a dictionary
representing the current local variables (names as keys).  "color" is looked
up as a key and its value substituted for "%(color)s".

With named substitution you can do all sorts of interesting things.  For
example, you can get it to search locals() then globals() with:

    d = {}
    d.update(globals())
    d.update(locals())

    "some formatting string" % d

You can get expression expansion on-the-fly as well (though check the
sources of your formatting strings - this can be a security hole!):

    class EvalDict:
        def __getitem__(self, key, locals=None, globals=None):
            caller = sys._getframe(1)
            if locals is None:
                locals = caller.f_locals
            if globals is None:
                globals = caller.f_globals
            return eval(key, locals, globals)

    "some formatting string" % EvalDict()

Or define your own interesting (to you) lookup semantics:

    class SuperDict(EvalDict):
        def __init__(self, *args):
            self.mydicts = args

        def __getitem__(self, key):
            # check user-specified dicts first
            for d in self.mydicts:
                try:
                    return d[key]
                except KeyError:
                    pass
            # fall back to expression eval
            caller = sys._getframe(1)
            return EvalDict.__getitem__(self, key, caller.f_locals, caller.f_globals)

    import math
    "%(sin(47))f" % SuperDict(math.__dict__)

With judicious fiddling of EvalDict you can also have recursive evaluation
of formatting strings like "%(sin(%(myvar)f)f".

and-you-thought-python-needed-a-preprocessor-ly, y'rs,

-- 
Skip Montanaro - skip at pobox.com
http://www.mojam.com/
http://www.musi-cal.com/




More information about the Python-list mailing list