Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String formatting in python

Recently I've been doing a lot of music based programming, and as such find myself doing this kind of thing a lot to deal with missing metadata in some songs:

default = {'title': 'Unknown title', 'artist': 'unknown Artist'}
default.update(song)
print '{title} - {artist}'.format(**default)

Is there a cleaner way to do this? I tried overriding __missing__ like so but missing keys still throw a KeyError:

class Song(dict):
    # dictionary with some nice stuff to make it nicer

    def __missing__(self, key):
        return 'Unknown {key}'.format(key = key)

Edit: Sorry I should have been clearer, basically the following must work.

s = Song()
print '{notAKey}'.format(s)

A couple of people have pointed out that the **s are not necessary.

Edit 2: I've "solved" my problem, at least to my satisfaction. It's debatable whether or not this is cleaner, but it works for me.

from string import Formatter

class DefaultFormatter(Formatter):

    def get_value(self, key, args, kwargs):
        # Try standard formatting, then return 'unknown key'

        try:
            return Formatter.get_value(self, key, args, kwargs)
        except KeyError:
            return kwargs.get(key, 'Unknown {0}'.format(key))

class Song(dict):

    def format(self, formatString):
        # Convenience method, create a DefaultFormatter and use it

        f = DefaultFormatter()
        return f.format(formatString, **self)

So the following will return 'Unknown notAKey'

k = Song()
print k.format('{notAKey}')
like image 874
Klohkwherk Avatar asked Aug 19 '11 20:08

Klohkwherk


1 Answers

Executive summary: encapsulate the song in a class.

It sounds to me like a song is a primary data type in your code and is worthy of having a dedicated class to represent it. By all means use a dict internal to the class to store the data but try and move to a higher level of abstraction than a dict.

You should be aiming for this class to provide all the services needed to support the operations you perform on songs. House all the formatting code in the class so that it isn't scattered about your code that uses the song items. Indeed you will find all sorts of operations that want to become methods of this class.

As for the implementation of the formatting, it doesn't matter if it's a little long-winded since you write it in one place only.

like image 147
David Heffernan Avatar answered Oct 21 '22 16:10

David Heffernan