ActiveState Code

Recipe 66018: Evaluating code inside strings


In Python, String and Unicode objects have one special operator: the % operator. With that operator, strings can be formatted with format codes. Formatting is given syntax format % values, where format is a string with format codes that are replaced with values. When value is any kind of mapping, formats must include parenthesis that contain a key. An item is fetched from directory with key or __getitem__ is overloaded with key. In this example, Eval's __getitem__ returns the result of eval(key).

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Eval:
    def __getitem__(self, key):
        return eval(key)

number = 19
text = "python"

print "%(text.capitalize())s %(number/9.0).1f rules!" % Eval()

#Python 2.1 rules!

Discussion

This solution can be useful because in order to do evaluations inside strings, strings must be constructed from many pieces. An alternative solution:

number = 19 text = "python" print text.capitalize()+" "+str(round(number/9.0,1))+" rules!"

Comments

  1. 1. At 9:48 p.m. on 13 jul 2001, p a said:

    faster to map. Hi,

    The form:

    g=[blah(i) for i in foo]
    

    is pretty tricky (I hadn't seen it before), but it's faster (and easier for me to read it) as:

    g=map(blah, foo)
    

    At least, it's faster on my timing tests.

  2. 2. At 9:53 p.m. on 13 jul 2001, p a said:

    Whoops. That comment was misplaced. I came back to the wrong link after signing in. Please delete it.

  3. 3. At 11:15 a.m. on 27 feb 2002, Anonymous said:

    More flexible string eval(). A somewhat more flexible version of Eval is:

    class Eval:
        def __init__(self, globals=None, locals=None):
            self.globals = globals or {}
            self.locals = locals or None
    
        def __getitem__(self, key):
            if self.locals is None:
                self.locals = sys._getframe(1).f_locals
            key = key % self
            return eval(key, self.globals, self.locals)
    

    It handles recursive formats such as "%(text.%(method)s)s" and works with local variables. You could get fancier and parameterize the number of frames to look up for locals. In practice, I find that's not generally necessary.

    My Eval is based on/stolen from something that Steve Majewski posted to c.l.py.

    Skip Montanaro (skip@pobox.com)

Sign in to comment