Refactoring; arbitrary expression in lists

Bengt Richter bokr at
Wed Jan 12 20:24:29 EST 2005

On Wed, 12 Jan 2005 18:16:23 +0000, Frans Englich <frans.englich at> wrote:

>As continuation to a previous thread, "PyChecker messages", I have a question 
>regarding code refactoring which the following snippet leads to:
>> > Function (detectMimeType) has too many returns (11)
>> >
>> > The function is simply a long "else-if" clause, branching out to
>> > different return statements. What's wrong? It's simply a "probably ugly
>> > code" advice?
>> That is also advice.  Generally you use a dict of functions, or some other
>> structure to lookup what you want to do.
>More specifically, my function looks like this:
>def detectMimeType( filename ):
>    extension = filename[-3:]
>    basename = os.path.basename(filename)
>    if extension == "php":
>        return "application/x-php"
>    elif extension == "cpp" or extension.endswith("cc"):
>        return "text/x-c++-src"
># etcetera
>    elif extension == "xsl":
>        return "text/xsl"
>    elif basename.find( "Makefile" ) != -1:
>        return "text/x-makefile"
>   else:
>        raise NoMimeError
>(don't bother if the MIME detection looks like stone age, it's temporary until 
>PyXDG gets support for the XDG mime type spec..)
>I'm now wondering if it's possible to write this in a more compact way, such 
>that the if-clause isn't necessary? Of course, the current code works, but 
>perhaps it could be prettier.
>I'm thinking along the lines of nested lists, but what is the obstacle for me 
>is that both the test and return statement are simple expressions; not  
>functions or a particular data type. Any ideas?
I think I would refactor along these lines: (untested)

    extensiondict = dict(
        php = 'application/x-php',
        cpp = 'text/x-c-src',
        # etcetera
        xsl = 'test/xsl'

    def detectMimeType(filename):
        extension = os.path.splitext(filename)[1].replace('.', '')
        try: return extensiondict[extension]
        except KeyError:
            basename = os.path.basename(filename)
            if "Makefile" in basename: return 'text/x-makefile' # XXX case sensitivity?
            raise NoMimeError

Bengt Richter

More information about the Python-list mailing list