ActiveState Code

Recipe 576883: Dict-like string formatting from an object by named atttributes


Formats a string using the same notation as a dict-expansion, but using an object as the source for the expansion instead. Attributes from the object are used as source to the expansions.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import re

exp_rx = re.compile('%\((\w+)\)')

def format_obj(obj, text):
    """
    >>> o = Duck(one='one', two='two', three=5)
    >>> format_obj(o, '%(one)s %(two)s %(three)d')
    'one two 5'
    """
    return text % dict((a, getattr(obj, a))
                               for a in re.findall(exp_rx, text))

# ---- Support for the doctest from here down:

class Duck(object):
    """Quack!"""

    def __init__(self, **kw):
        self.__dict__.update(kw)

if __name__ == '__main__':
    import doctest
    doctest.testmod()

Comments

  1. 1. At 5:17 p.m. on 17 aug 2009, Chris Jones said:

    I like over-riding the __repr__ method myself:

    class Duck(object):
    
        '''
        >>> Duck(foo=1, bar='2', baz=None)
        <Duck object at 0x28b3a4ec: bar='2', foo=1, baz=None>
        >>> Duck()
        <Duck object at 0x28b36d6c>
        '''
    
        def __init__(self, **kwargs):
            self.__dict__.update(kwargs)
    
        def __repr__(self):
            a = ', '.join('%s=%r' % i for i in self.__dict__.items())
            return '<%s object at 0x%x%s%s>' % (
                    type(self).__name__, id(self), ': ' if a else '', a)
    

    You can get fancier with it, e.g. skipping private attributes, but I mostly use it for development/debugging and remove it later.

  2. 2. At 9:55 p.m. on 17 aug 2009, Manfred Moitzi said:

    Hello!

    You got the same result with:

    return text % obj.__dict__
    

    What is the advantage of your recipe?

  3. 3. At 1:22 p.m. on 18 aug 2009, Gabriel Genellina said:

    Or even simpler:

    return text % vars(obj)
    

Sign in to comment