Более точный способ импортировать модуль из нескольких мест? - PullRequest
10 голосов
/ 23 декабря 2008

Есть ли способ привести в порядок следующий код, а не ряд вложенных операторов try / исключением?

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!"

Ответы [ 5 ]

7 голосов
/ 23 декабря 2008

Я обнаружил следующую функцию в http://mail.python.org/pipermail/python-list/2007-May/441896.html. Кажется, она работает довольно хорошо, и я уверен, что ее импорт не скомпрометирует существующие операции импорта, которые у вас уже есть.

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')

Я знаю, что это похоже на дополнительный код, но эту функцию можно использовать в другом месте, если вы делаете это много.

3 голосов
/ 23 декабря 2008
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')
1 голос
/ 24 января 2019

Это позволяет избежать вложения, но я не уверен, что оно лучше :)

json = None

if json is None:
    try:
        import json
    except ImportError:
        pass

if json is None:
    try:
        import simplejson as json
    except ImportError:
        pass

if json is None:
    try:
        from django.utils import simplejson as json
    except ImportError:
        pass    

if json is None:
    raise ImportError('Requires either simplejson, Python 2.6 or django.utils')
1 голос
/ 23 декабря 2008

Я ценю красивые функции для этого, но шаблон, который вы иллюстрируете в исходном вопросе, является наиболее часто используемым шаблоном для этого требования. Вы можете видеть, что он используется во многих проектах с открытым исходным кодом.

Я предлагаю вам придерживаться этого. Помните, что "некрасиво" не всегда "плохо".

0 голосов
/ 29 июня 2015

Я предложил простую альтернативу, которая не зависит от определения функций:

# Create a dummy enclosing
while True:
    try:
        import simplejson as json
        break
    except:
        pass

    try:
        import json
        break
    except:
        pass

    try:
        from django.utils import simplejson as json
        break
    except:
        pass

    raise ImportError('Requires either simplejson, Python 2.6 or django.utils')

Обратите внимание, я не совсем уверен, красивее ли это, чем подход с использованием вспомогательной функции.

...