淘派電商 > 嵌入式技術 > 編程語言及工具 > 正文

導入Python庫失敗的缺失庫怎麼解決

2020年11月21日 11:46 次閲讀

在寫Python項目的時候,我們可能經常會遇到導入模塊失敗的錯誤:ImportError:Nomodulenamed'xxx'或者ModuleNotFoundError:Nomodulenamed'xxx'。

導入失敗問題,通常分為兩種:一種是導入自己寫的模塊(即以.py為後綴的文件),另一種是導入三方庫。本文主要討論第二種情況,今後有機會,我們再詳細討論其它的相關話題。

解決導入Python庫失敗的問題,其實關鍵是在運行環境中裝上缺失的庫(注意是否是虛擬環境),或者使用恰當的替代方案。這個問題又分為三種情況:

一、單個模塊中缺失的庫

在編寫代碼的時候,如果我們需要使用某個三方庫(如requests),但不確定實際運行的環境是否裝了它,那麼可以這樣:

try:importrequestsexcepTImportError:importosos.system('pipinstallrequests')importrequests

這樣寫的效果是,如果找不到requests庫,就先安裝,再導入。

在某些開源項目中,我們可能還會看到如下的寫法(以json為例):

try:importsimplejsonasjsonexcepTImportError:importjson

這樣寫的效果是,優先導入三方庫simplejson,如果找不到,那就使用內置的標準庫json。

這種寫法的好處是不需要導入額外的庫,但它有個缺點,即需要保證那兩個庫在使用上是兼容的,如果在標準庫中找不到替代的庫,那就不可行了。

如果真找不到兼容的標準庫,也可以自己寫一個模塊(如my_json.py),實現想要的東西,然後在except語句中導入它。

try:importsimplejsonasjsonexcepTImportError:importmy_jsonasjson

二、整個項目中缺失的庫

以上的思路是針對開發中的項目,但是它有幾個不足:
1、在代碼中對每個可能缺失的三方庫都pipinstall,並不可取;
2、某個三方庫無法被標準庫或自己手寫的庫替代,該怎麼辦?
3、已成型的項目,不允許做這些修改怎麼辦?

所以這裏的問題是:有一個項目,想要部署到新的機器上,它涉及很多三方庫,但是機器上都沒有預裝,該怎麼辦?

對於一個合規的項目,按照約定,通常它會包含一個“requirements.txt”文件,記錄了該項目的所有依賴庫及其所需的版本號。這是在項目發佈前,使用命令pipfreeze>requirements.txt生成的。

使用命令pipinstall-rrequirements.txt(在該文件所在目錄執行,或在命令中寫全文件的路徑),就能自動把所有的依賴庫給裝上。

但是,如果項目不合規,或者由於其它倒黴的原因,我們沒有這樣的文件,又該如何是好?

一個笨方法就是,把項目跑起來,等它出錯,遇到一個導庫失敗,就手動裝一個,然後再跑一遍項目,遇到導庫失敗就裝一下,如此循環……(此處省略1萬句髒話)……

三、自動導入任意缺失的庫

有沒有一種更好的可以自動導入缺失的庫的方法呢?

在不修改原有的代碼的情況下,在不需要“requirements.txt”文件的情況下,有沒有辦法自動導入所需要的庫呢?

當然有!先看看效果:


我們以tornado為例,第一步操作可看出,我們沒有裝過tornado,經過第二步操作後,再次導入tornado時,程序會幫我們自動下載並安裝好tornado,所以不再報錯。

autoinstall是我們手寫的模塊,代碼如下:

#以下代碼在python3.6.1版本驗證通過importsysimportosfromimportlibimporTImport_moduleclassAutoInstall():_loaded=set()@classmethoddeffind_spec(cls,name,path,target=None):ifpathisNoneandnamenotincls._loaded:cls._loaded.add(name)print("Installing",name)try:result=os.system('pipinstall{}'.format(name))ifresult==0:returnimport_module(name)exceptExceptionase:print("Failed",e)returnNonesys.meta_path.append(AutoInstall)

這段代碼中使用了sys.meta_path,我們先打印一下,看看它是個什麼東西?


Python3的import機制在查找過程中,大致順序如下:
•在sys.modules中查找,它緩存了所有已導入的模塊
•在sys.meta_path中查找,它支持自定義的加載器
•在sys.path中查找,它記錄了一些庫所在的目錄名
•若未找到,拋出ImportError異常

其中要注意,sys.meta_path在不同的Python版本中有所差異,比如它在Python2與Python3中差異很大;在較新的Python3版本(3.4+)中,自定義的加載器需要實現find_spec方法,而早期的版本用的則是find_module。


以上代碼是一個自定義的類庫加載器AutoInstall,可以實現自動導入三方庫的目的。需要説明一下,這種方法會“劫持”所有新導入的庫,破壞原有的導入方式,因此也可能出現一些奇奇怪怪的問題,敬請留意。

sys.meta_path屬於Python探針的一種運用。探針,即importhook,是Python幾乎不受人關注的機制,但它可以做很多事,例如加載網絡上的庫、在導入模塊時對模塊進行修改、自動安裝缺失庫、上傳審計信息、延遲加載等等。

限於篇幅,我們不再詳細展開了。

最後小結一下:
•可以用try…except方式,實現簡單的三方庫導入或者替換
•已知全部缺失的依賴庫時(如requirements.txt),可以手動安裝
•利用sys.meta_path,可以自動導入任意的缺失庫

參考資料:
//github.com/liuchang0812/slides/tree/master/pycon2015cn
//blog.konghy.cn/2016/10/25/python-import-hook
//docs.python.org/3/library/sys.html#sys.meta_path

編輯:hfy


下載發燒友APP

打造屬於您的人脈電子圈

關注淘派電商微信

有趣有料的資訊及技術乾貨

關注發燒友課堂

鎖定最新課程活動及技術直播

淘派電商觀察

一線報道 · 深度觀察 · 最新資訊
收藏 人收藏
分享:

評論

相關推薦

零基礎Python入門教程二

隨着新技術的不斷推進,在未來無論你要進入網頁開發、數據分析、機器學習、人工智能還是無人車等領域,Python 都是必不可
發燒友學院發表於 2019-04-09 00:00 0次閲讀
零基礎Python入門教程二

C#良好兼容了值類型/引用類型

反觀歷史,C#也曾經因為 值類型/引用類型 保守詬病,“拆箱”和“裝箱”一直是個招黑的設計。但後來我....
發表於 2020-11-20 10:14 65次閲讀
C#良好兼容了值類型/引用類型

Python逐漸失去魅力

自從20世紀90年代初發布以來,Python一直相當火爆,在這二十多年裏,它的流行程度遠遠超過了C、....
發表於 2020-11-19 11:05 147次閲讀
Python逐漸失去魅力

Python20年來首次超越Java

根據 2020 年 11 月最新出爐的 TIOBE 編程語言排行榜,Python 以 12.12% ....
發表於 2020-11-16 11:28 267次閲讀
Python20年來首次超越Java

請問python文件怎麼操作?

python文件的操作步驟
發表於 2020-11-16 07:53 0次閲讀
請問python文件怎麼操作?

【淘派電商】零基礎學python_04_字符串(刪除空白)分析

刪除字符串中的空白: 在程序中,額外的空白可能令人迷惑。對程序員來説,'python' 和'python ' 看起來幾乎沒什麼...
發表於 2020-11-14 11:24 404次閲讀
【淘派電商】零基礎學python_04_字符串(刪除空白)分析

出現ImportError: No module named PyQt4.QtGui的解決方法

將python3.7版本環境(圖中前兩個)上移到最上層,用户變量和系統變量都要調。...
發表於 2020-11-14 00:03 101次閲讀
出現ImportError: No module named PyQt4.QtGui的解決方法

Python 之父正式加入微軟

11月13日消息 去年 10 月, Python 創始人 Guido van Rossum 在 Dr....
發表於 2020-11-13 17:39 315次閲讀
Python 之父正式加入微軟

【淘派電商】十運行python程序建立web網站

一直想在kindle電子書屏幕上作為樹莓派或者maaxboard開發板的顯示器,刷新速度雖然慢,但是編程調試夠用。 之前瞭解...
發表於 2020-11-13 15:09 202次閲讀
【淘派電商】十運行python程序建立web網站

Python 創始人復出 宣佈已加入微軟開發者部...

去年 10 月, Python 創始人 Guido van Rossum 在 Dropbox 公司工....
發表於 2020-11-13 11:41 250次閲讀
Python 創始人復出 宣佈已加入微軟開發者部...

人工智能行業,編程學習是Python還是C++好...

很多想要進入人工智能行業的開發者都會糾結於學習Python還是學習C++。有些人認為,Python目....
發表於 2020-11-13 09:29 279次閲讀
人工智能行業,編程學習是Python還是C++好...

零基礎學python_03_字符串(拼接+換行+製表符)

字符串拼接 在編碼的過程很多時候都會用到字符串的拼接,例如,你可能想將姓和名存儲在不同的變量中,等要顯示姓名時...
發表於 2020-11-11 15:30 303次閲讀
零基礎學python_03_字符串(拼接+換行+製表符)

不再低調,QuecPython橫空出世

移遠通信正式推出一套輕鬆上手、功能完善的嵌入式操作系統——QuecPython,可讓客户基於移遠模組....
發表於 2020-11-11 11:49 515次閲讀
不再低調,QuecPython橫空出世

如何用Python給頭像添加國旗?

用Python給頭像添加國旗的方法
發表於 2020-11-11 08:02 0次閲讀
如何用Python給頭像添加國旗?

求python小案例demo01?

python小案例demo01
發表於 2020-11-10 07:18 0次閲讀
求python小案例demo01?

Python仍是人工智能和機器學習的主導編程語言...

上世紀90年代初,Python面世了。近30年來,關於它的“炒作”一直沒有少過。當然,編程界花了至少....
發表於 2020-11-09 14:30 451次閲讀
Python仍是人工智能和機器學習的主導編程語言...

請問Python中的類方法、實例方法和靜態方法是什麼?

Python中的類方法、實例方法和靜態方法
發表於 2020-11-09 07:13 0次閲讀
請問Python中的類方法、實例方法和靜態方法是什麼?

最新的編程語言排行説明Python衝上第二

本月的排行榜出現了自 TIOBE 榜單發佈以來,近二十年從未見過的變化:前兩名的位置首次出現了一個除....
發表於 2020-11-07 10:54 383次閲讀
最新的編程語言排行説明Python衝上第二

怎樣使用Python創建詞雲

介紹從開始從事數據可視化工作的那一天起,我就愛上它了,我總是喜歡從數據中獲得有用的見解。在此之前,我....
發表於 2020-11-06 17:26 296次閲讀
怎樣使用Python創建詞雲

高煥堂老師《AI概論:來來來,成為AI的良師益友》(全文)

這是一本非常基礎的 AI 入門書籍。AI 的與會比傳統IT(信息)有趣的地方是,當今 AI 的基礎是:機器學習(Machi...
發表於 2020-11-06 17:25 909次閲讀
高煥堂老師《AI概論:來來來,成為AI的良師益友》(全文)

請問Python中如何實現vlookup函數的功能?

vlookup函數功能非常強大,那在Python中如何實現?...
發表於 2020-11-06 06:11 0次閲讀
請問Python中如何實現vlookup函數的功能?

Python3.9的新特性必知圖

Python3.9,「千呼萬喚始出來」。 先來速看下此次發佈版本的重點。 新語法特性: PEP 58....
發表於 2020-11-05 15:33 332次閲讀
Python3.9的新特性必知圖

Python 在未來十年內仍是機器學習的首選語言

愚者多怨,仁者不言,生活中就是會有很多愛唱反調的人,但不管怎麼説Python 在接下來十年仍然會很重....
發表於 2020-11-05 14:38 303次閲讀
Python 在未來十年內仍是機器學習的首選語言

能夠指揮AI機器的編程網紅Python,被譽為“...

在這樣的背景之下,我國也非常重視Python的教育:浙江已經把Python列為中學生必修項目;山東、....
發表於 2020-11-05 14:09 520次閲讀
能夠指揮AI機器的編程網紅Python,被譽為“...

20年來首次:Java被編程語言 Python超...

日前,TIOBE公佈了最新一期的編程語言排行榜(11月)。 接近20年來的首次,Java和C沒有分享....
發表於 2020-11-05 13:28 313次閲讀
20年來首次:Java被編程語言 Python超...

20年來首次。Java掉出全球最受歡迎的兩大編程...

日前,TIOBE公佈了最新一期的編程語言排行榜(11月)。接近20年來的首次,Java和C沒有分享前....
發表於 2020-11-05 12:11 204次閲讀
20年來首次。Java掉出全球最受歡迎的兩大編程...

如何利用Python判斷統計每個月天數源

如何利用Python判斷統計每個月天數源。在日常的學習或是工作中會經常遇到需要統計日期數據的情況。特....
發表於 2020-11-02 09:41 345次閲讀
如何利用Python判斷統計每個月天數源

如何基於 ES6 的 JavaScript 進行...

TensorFlow.js 是 TensorFlow 的 JavaScript 版本,支持 GPU ....
發表於 2020-10-31 11:16 574次閲讀
如何基於 ES6 的 JavaScript 進行...

在Python中實現異步編程(附源碼)

異步編程是並行編程的一種方式。單個工作單元獨立於主應用程序線程運行,並通知調用線程其完成、失敗情況或....
發表於 2020-10-27 14:36 363次閲讀
在Python中實現異步編程(附源碼)

世界上最深奧的編程語言有哪些

當我們談論 c,c++ ,Java,Python的時候,有些語言不僅很難,而且對於大多數軟件開發者來....
發表於 2020-10-25 10:13 327次閲讀
世界上最深奧的編程語言有哪些

TIOBE已公佈2020年10月的編程語言排行榜

Python從去年開始就已經登上了TIOBE榜單的第三位,但它的受歡迎程度一直在上升,本月,該指數達....
發表於 2020-10-23 10:41 5783次閲讀
TIOBE已公佈2020年10月的編程語言排行榜

Python受歡迎程度直上升 即將超過Java

來自:程序猿(ID:imkuqin) TIOBE已公佈2020年10月的編程語言排行榜。C語言依然排....
發表於 2020-10-23 10:41 400次閲讀
Python受歡迎程度直上升 即將超過Java

Go為什麼是2020年最受歡迎的語言?

在接下來的幾年中,Python無疑還將繼續在這些領域佔據主導地位。但是,與一些新興語言相比,它存在一....
發表於 2020-10-23 10:37 357次閲讀
Go為什麼是2020年最受歡迎的語言?

STM32的backtrace深度講解(cort...

STM32上的backtrace原理與分析 1.説明 2.cortex-m上的棧佈局 2.1 cor....
發表於 2020-10-22 15:13 576次閲讀
STM32的backtrace深度講解(cort...

2020年10月編程語言排行榜:Python即將...

來源:菜鳥教程 TIOBE 2020 年 10 月份的編程語言排行榜已經公佈,官方的標題是:Pyth....
發表於 2020-10-19 11:37 521次閲讀
2020年10月編程語言排行榜:Python即將...

為什麼一定要學Python 答案太扎心了

今年秋招太難了。畢業生們紛紛表示心酸: 投了100份簡歷,面試邀請為0;別説大公司了,就連名不見經傳....
發表於 2020-10-13 17:36 356次閲讀
為什麼一定要學Python  答案太扎心了

集中討論谷歌、亞馬遜等技術巨頭使用Python開...

十年前,由於編程語言種類匱乏,開發人員不必苦惱自己應該選擇哪一種編程語言;但是現在,世界上正在使用的....
發表於 2020-10-11 09:51 550次閲讀
集中討論谷歌、亞馬遜等技術巨頭使用Python開...

Python編程已經走進中小學課堂

在編程世界,關於哪個語言是最好的爭論從未停止,雖然道理誰也不服誰,但是關於編程的熱度,我們可以從TI....
發表於 2020-10-10 17:10 400次閲讀
Python編程已經走進中小學課堂

如何系統型的學習深度學習?

更要命的是,我發現我一直都是在寫算法,從沒考慮過如何部署模型,也就是整天紙上談兵。所以我最近開始學網....
發表於 2020-10-10 10:39 367次閲讀
如何系統型的學習深度學習?

10個流行的Python庫平台

作為開發人員喜愛的語言之一,Python以其豐富的社區可用工具和庫而聞名。我們列出了開發人員可以用於....
發表於 2020-10-09 16:33 314次閲讀
10個流行的Python庫平台

Python在人工智能領域為什麼如此受歡迎?

人工智能已成為我們日常生活不可或缺的一部分,它被廣泛地應用到幾百種實際場景中,極大地便利人們的工作和....
發表於 2020-09-30 11:09 470次閲讀
Python在人工智能領域為什麼如此受歡迎?