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

в най-горното ниво на вашия модул. Това е начинът на Pythonic за справяне с тази ситуация.

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