2009-10-24 46 views
4

如果用戶嘗試運行嘗試導入尚未安裝的模塊的python腳本,我想實現一些友好的錯誤消息。這包括打印如何安裝缺少的模塊的說明。這樣做將是把進口圍繞try..catch塊關於爲缺少的模塊導入的Friendlier錯誤消息

的一種方式,但是這是一個有點難看,因爲它會變成一些簡單的像

import some_module 

try: 
    import some_module 
except ImportError, e: 
    handle_error(e) 

,它將不得不被添加到每個文件。此外,ImportError似乎沒有在任何地方存儲缺失模塊的名稱(除了在消息中),因此如果您需要知道名稱(比如我),則必須在每次導入時分別放置try..catch, 。解析模塊的名稱不是選項,因爲ImportError攜帶的消息可能會更改爲python版本,並取決於用戶的區域設置。

我想我可以使用sys.excepthook來捕獲所有的異常,並通過除了ImportError之外。 還是有可能定義類似

safe_import some_module 

會表現得像我想要的嗎?

有沒有人知道這個問題的任何現有解決方案?

回答

2

我會將其他模塊放入包中,導入時會打印出更有用的消息,然後引發常規ImportError。當安裝真正的模塊時,你的模塊會被遮蔽(確保你在sys.path的處添加他們所在的目錄)。

+0

我想,這可能是最好的建議的解決方案。它不依賴任何特殊的「技巧」,因爲它應該非常強大。同時,它不需要對源代碼進行任何更改(除了可以添加正確的路徑到sys.path,這可以輕鬆處理)。 – pafcu 2009-10-25 14:06:49

5

你可以說,地方,它都會被執行(例如,在site.py或sitecustomize.py):

import __builtin__ 

realimport = __builtin__.__import__ 

def myimport(modname, *a): 
    try: 
    return realimport(modname, *a) 
    except ImportError, e: 
    print "Oops, couldn't import %s (%s)" % (modname, e) 
    print "Here: add nice directions and whatever else" 
    raise 

__builtin__.__import__ = myimport 

__import__文檔here

+0

我想這個問題的一個問題是,如果有其他人提出了相同的想法,它不會很好地發揮。如果其他軟件包使用相同的技巧,那麼你運氣不好(因爲如果__import__它會安裝另一個版本)。 – pafcu 2009-10-25 14:03:37

3

您不必爲每個導入都捕獲ImportError。您可以在腳本的入口點使用全局的try..except塊。

您可以使用message屬性從ImportError實例中獲取缺失模塊的名稱。

例如,如果你的腳本的入口點是main.py:

if __name__ == '__main__': 
    try: 
     import module1 
     import module2 

     module1.main() 
    except ImportError as error: 
     print "You don't have module {0} installed".format(error.message[16:]) 

不要try..except塊的外部輸入任何東西。這將覆蓋模塊1和模塊2及其導入的所有模塊等。

正如你所說,你可以定義自己的import_safe功能:

def import_safe(module): 
    try: 
     return __import__(module) 
    except ImportError as error: 
     print "You don't have module {0} installed".format(error.message[16:]) 

然後你可以使用的功能:

sys = import_safe('sys') 
gtk = import_safe('gkt') 

在我看來,拳頭策略較好。第二個會讓你的代碼難以閱讀。並將改變語言的重要部分。

+0

第一種方法的問題是它試圖解析錯誤消息(甚至沒有,它只是假定模塊名稱在特定位置)。這只是不能假設:錯誤消息可能是本地化的或在Python版本 – pafcu 2009-10-24 20:02:59

+0

而不是'print「之間進行更改您沒有安裝模塊{0}」.format(error.message [16:]) '只是**'打印(錯誤)'**對於2.7.10和3.5.0都適用 – CrandellWS 2015-10-15 01:40:49

1

更換sys.excepthook

orig_excepthook = sys.excepthook 

def my_excepthook(type, value, tb): 
    orig_excepthook(type, value, tb) 
    if issubclass(type, ImportError): 
     # print some friendly message 

sys.excepthook = my_excepthook