views:

245

answers:

3

Is there a way to tidy-up the following code, rather than a series of nested try/except statements?

try:
    import simplejson as json
except ImportError:
    try:
        import json
    except ImportError:
        try:
            from django.utils import simplejson as json
        except:
            raise "Requires either simplejson, Python 2.6 or django.utils!"
+6  A: 

I found the following function at http://mail.python.org/pipermail/python-list/2007-May/441896.html. It seems to work quite well, and I'm pretty sure the way its importing won't stomp on any existing imports you might already have.

def module_exists(module_name):
    try:
        mod = __import__(module_name)
    except ImportError:
        return False
    else:
        return True

if module_exists('simplejson'):
    import simplejson as json
elif module_exists('json'):
    import json
elif module_exists('django.utils'):
    from django.utils import simplejson as json
else:
    raise ImportError('Requires either simplejson, Python 2.6 or django.utils')

I know this seems like more code, but the function is reusable elsewhere if you're doing a lot of this.

Soviut
+2  A: 
def import_any(*mod_list):
    res = None
    for mod in mod_list:
        try:
            res = __import__(mod)
            return res
        except ImportError:
            pass
    raise ImportError("Requires one of " + ', '.join(mod_list))

json = import_any('simplejson', 'json', 'django.utils.simplejson')
zakhar
+1  A: 

I appreciate the pretty functions for doing this, but the pattern you illustrate in the original question is the most commonly used pattern for this requirement. You can see it used in many open source projects.

I suggest you stick with it. Remember "ugly" is not always "bad".

Ali A