Python перехватывает NameError при загрузке модуля

Я пытаюсь отловить любые исключения, которые случаются, когда вы не можете загрузить модуль. Текущие результаты таковы, что блок «кроме» не выполняется.

import sys 
def loadModule(module):
   try: 
      import module
   except: 
      print """ 
      Cannot load %s
      For this script you will need: 
         cx_Oracle:  http://cx-oracle.sourceforge.net/
         pycrypto:   https://www.dlitz.net/software/pycrypto/
         paramiko:   http://www.lag.net/paramiko/
       """ % module
      sys.exit(1)

loadModule(cx_Oracle)

Ошибка:

Traceback (most recent call last):
  File "./temp_script.py", line 16, in <module>
    loadModule(cx_Oracle)
NameError: name 'cx_Oracle' is not defined

person Simply Seth    schedule 30.08.2012    source источник


Ответы (3)


loadModule(cx_Oracle)

Как вы думаете, что вы передаете этой функции? В коде пока нет ничего с именем cx_Oracle. Вот почему вы получаете ошибку NameError. Вы даже не входите в функцию.

 import module

Вы не можете передавать переменные для импорта, он интерпретирует то, что вы вводите, как буквальное имя модуля.

В этом случае я сомневаюсь, что вам вообще нужна функция. Просто переместите try / except на уровень модуля и напрямую импортируйте cx_Oracle.

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

from contextlib import contextmanager
import sys

@contextmanager
def safe_import(name):
    try:
        yield
    except:
        print 'Failed to import ' + name
        sys.exit(1)

with safe_import('cuckoo'):
    import cuckoo
person Winston Ewert    schedule 30.08.2012

Ошибка возникает, когда Python пытается найти переменную cx_Oracle до того, как функция loadModule даже может быть вызвана.

Если вы хотите сохранить свою текущую стратегию, вы, вероятно, действительно захотите использовать что-то вроде importlib .import_module, чтобы можно было импортировать модуль по имени, например import_module('cx_Oracle').

Я бы предложил вместо этого сделать что-то вроде этого:

try:
    import cx_Oracle
except ImportError:
    print "Can't load the Oracle module"
    dosomething()

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

person Kirk Strauser    schedule 30.08.2012

Всегда думайте, какое исключение вы хотите перехватить. Не преувеличивайте, просто кодируя except:. В этом случае вы хотите поймать ImportError. Аргумент, который вы хотите передать своей функции loadModule, должен быть строкового типа, например. loadModule('cx_Oracle') (тогда вы избавитесь от NameError). Для динамической загрузки модулей в loadModule просмотрите, например, динамическую загрузку модулей Python.

person Dr. Jan-Philip Gehrcke    schedule 30.08.2012