2009-04-20 158 views
7

如果給出模塊的名稱,我們如何測試是否安裝了一組模塊。例如。測試是否安裝了Python模塊依賴關係

modules = set(["sys", "os", "jinja"]) 

for module in modules: 
    # if test(module exists): 
    # do something 

雖然可以寫出來的測試爲:

try: 
    import sys 
except ImportError: 
    print "No sys!" 

這是我在做什麼有點麻煩。有沒有一種動態的方式來做到這一點?

我試過eval(「import%s」%module)但抱怨編譯錯誤。

我很感激您的想法和建議。謝謝。

回答

8

您可以使用這樣的__import__()功能::

for module in modules: 
    try: 
     __import__(module) 
    except ImportError: 
     do_something() 

您還可以使用imp.find_module來確定模塊是否能找到沒有其導入::

import imp 
for module in modules: 
    try: 
     imp.find_module(module) 
    except ImportError: 
     do_something() 

哦,而你不能使用eval()的原因是因爲import是一個語句,而不是表達式。您可以使用exec如果你真的想,雖然我不會推薦它::

for module in modules: 
    try: 
     exec 'import ' + module 
    except ImportError: 
     do_something() 
6

這是怎麼回事?

modules = set(["sys", "os", "jinja"]) 
for m in modules: 
    try: 
     __import__(m) 
    except ImportError: 
     # do something 

以上使用__import__函數。此外,它嚴格測試它是否存在 - 它實際上並不在任何地方保存導入,但可以輕鬆修改它以執行此操作。

2
modules = set(["sys", "os", "jinja"]) 
try: 
    for module in modules: 
    __import__(module) 
    doSomething() 
except ImportError, e: 
    print e 
5

值得理解find_module方法和__import__方法之間的權衡:

  • __import__('foo')將觸發加載模塊的任何副作用,而不管是否保存對導入模塊的引用。這可能是好的,或不。
  • find_module('foo')不會觸發任何副作用,所以它應該始終是安全的。
  • 沒有辦法效果很好,如果模塊被發現,但在加載時(例如SyntaxError錯誤,NameError,...)
  • 其他問題取決於你如何處理故障,只需/包裝__import__('foo')在try除了會給你誤導結果,如果發現富,但富進口酒吧,這是而不是找到。
  • find_module()不能處理帶點名稱,因此,如果您需要檢查「foo.bar.bat.baz」是否可以進口的,你必須使用多次調用find_module和load_module爲每docs.