Refactoring; arbitrary expression in lists

Paul McGuire ptmcg at austin.rr._bogus_.com
Wed Jan 12 13:34:54 EST 2005


"Frans Englich" <frans.englich at telia.com> wrote in message
news:mailman.576.1105553330.22381.python-list at python.org...
>
> As continuation to a previous thread, "PyChecker messages", I have a
question
> regarding code refactoring which the following snippet leads to:
>
> > > runner.py:200: 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
<snip>

Since the majority of your tests will be fairly direct 'extension "XYZ"
means mimetype "aaa/bbb"', this really sounds like a dictionary type
solution is called for.  Still, you might have some desire to do some
order-dependent testing.  Here are two ideas - the first iterates over a
list of expressions and resulting types, the other uses a dictionary lookup.

-- Paul


import os

extToMimeMap = [
    ('"php"', "application/x-php"),
    ('"cpp" or extension.endswith("cc")', "text/x-c++-src"),
    ('"xsl"', "text/xsl"),
    ]

def detectMimeType1( filename ):

    extension = filename[-3:]
    basename = os.path.basename(filename)

    for exp,mimetype in extToMimeMap:
        if eval("extension=="+exp): return mimetype

    # do other non-extension-related tests here
    if basename.find( "Makefile" ) != -1:
        return "text/x-makefile"
    else:
        raise NoMimeError


extToMimeDict = {
    "php": "application/x-php",
    "cpp": "text/x-c++-src",
    "xsl": "text/xsl",
    }

def detectMimeType2( filename ):

    extension = filename[-3:]
    basename = os.path.basename(filename)

    # check for straight extension matches
    try:
        return extToMimeDict[extension]
    except KeyError:
        pass

    # do more complex extension and other non-extension-related tests here
    if extension.endswith("cc"):
        return extToMimeDict["cpp"]

    if basename.find( "Makefile" ) != -1:
        return "text/x-makefile"

    raise NoMimeError

for detectMimeType in (detectMimeType1, detectMimeType2):
    for s in ("a.php","z.acc","Makefile","blork.xsl"):
        print s,"->",detectMimeType(s)






More information about the Python-list mailing list