Python導(dǎo)入模塊時遇到的錯誤分析
當(dāng)遇到無法導(dǎo)入某個python模塊時,可能會是沒有安裝某個模塊,也有可能是某模塊在加載過程中失敗,也有可能是陷入了循環(huán)導(dǎo)入的問題。本文詳細(xì)解釋了這個問題。
1. 模塊未安裝或者路徑不對
ImportError: No mudule named myModule
有兩種可能,一是該模塊沒有安裝,一般可以用
pip install %module_name%
來解決。注意有時候模塊安裝包名并不等于要導(dǎo)入的模塊名。這種情況下可以通過pip search | list命令來嘗試找到正確的包。
另一種情況就是包雖然安裝了,但當(dāng)前運行的程序加載的路徑有錯。python運行時將從以下位置嘗試加載python modules:
* 當(dāng)前目錄
* 環(huán)境變量$PYTHONPATH所指示的值,這是一個由“:”分隔的字符串,各個子字符串都是文件系統(tǒng)的一個路徑。
* 標(biāo)準(zhǔn)庫目錄,如dist-site-packages下的模塊。
* 在.pth文件中指定的路徑,如果存在.pth文件的話。
可以使用以下方式來查看python運行時的包含路徑:
import sys print(sys.path)
在運行出錯的腳本裝頭部加上這一段代碼,然后在控制臺中查看打印出來的python類庫路徑,檢查安裝包是否已包含在上述路徑中。
***可以通過下面的方式將未包含在路徑中的模塊臨時包含進來:***
sys.path.append("path/to/module")
另外,還可以在shell窗口中查看當(dāng)前的python包含路徑:
echo $PYTHONPATH
2. 無法導(dǎo)入已存在的模塊
如果要導(dǎo)入的模塊包含了native代碼,并且native代碼加載(初始化)失敗時,就會導(dǎo)致這種錯誤。使用ssl, gevent等涉及native的模塊時,如果對應(yīng)的native程序并未安裝,則會出現(xiàn)這樣的錯誤。
另一種錯誤情況是,使用相對路徑導(dǎo)入時,父模塊還未導(dǎo)入成功。見下面的代碼:
main.py mypackage/ __init__.py mymodule.py myothermodule.py
mymodule.py如下所示:
#!/usr/bin/env python3 # Exported function def as_int(a): return int(a) # Test function for module def _test(): assert as_int('1') == 1 if __name__ == '__main__': _test()
以及myothermodule代碼如下所示:
#!/usr/bin/env python3 from .mymodule import as_int # Exported function def add(a, b): return as_int(a) + as_int(b) # Test function for module def _test(): assert add('1', '1') == 2 if __name__ == '__main__': _test()
如果執(zhí)行mypackage/myothermodule,則會報以下錯誤:
Traceback (most recent call last):
File "myothermodule.py", line 3, in <module>
from .mymodule import as_int
SystemError: Parent module '' not loaded, cannot perform relative import
[這篇文章](#Relative imports in Python 3)給出了更詳細(xì)的解答。
3. 循環(huán)導(dǎo)入
這種錯誤稱之為"circular (or cyclic) imports"。是python獨有的一種導(dǎo)入錯誤,在象java這樣的語言中就不存在。
假設(shè)有如下兩個文件,a.py和b.py:
#a.py print "a in" import sys print "b imported: %s" % ("b" in sys.modules, ) import b print "a out" print b.x
以及:
#b.py print "b in" import a print "b out" x = 3
執(zhí)行python a.py,將得到以下結(jié)果:
$ python a.py a in b imported: False b in a in b imported: True a out Traceback (most recent call last): File "a.py", line 4, in <module> import b File "/home/shlomme/tmp/x/b.py", line 2, in <module> import a File "/home/shlomme/tmp/x/a.py", line 7, in <module> print b.x AttributeError: 'module' object has no attribute 'x'
出現(xiàn)這種情況的原因是產(chǎn)生了循環(huán)導(dǎo)入。循環(huán)導(dǎo)入,以及在導(dǎo)入過程中python進行了加鎖操作,最終導(dǎo)致在模塊b未導(dǎo)入完成時就引用了其中的名字。
判斷導(dǎo)入錯誤是否是因為循環(huán)導(dǎo)入引起的,主要看堆棧中是否出現(xiàn)兩次重復(fù)的導(dǎo)入。比如上述堆棧中a.py出現(xiàn)兩次,因此可以判斷是這個文件引起的循環(huán)導(dǎo)入。
要解決這個問題,可以把模塊看成一種資源,對所有要引入的模塊進行編號,再按靜態(tài)資源排序法順次導(dǎo)入,就可以避免循環(huán)導(dǎo)入。
相關(guān)文章
python實現(xiàn)自動登錄人人網(wǎng)并訪問最近來訪者實例
這篇文章主要介紹了python實現(xiàn)自動登錄人人網(wǎng)并訪問最近來訪者實例,該實例是在前面登錄人人網(wǎng)實例基礎(chǔ)上的擴展,是非常實用的一個技巧,需要的朋友可以參考下2014-09-09Python實現(xiàn)對數(shù)坐標(biāo)系繪制與自定義映射
這篇文章主要為大家學(xué)習(xí)介紹了如何利用Python實現(xiàn)對數(shù)坐標(biāo)系繪制與坐標(biāo)自定義映射,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-08-08Python+pyftpdlib實現(xiàn)局域網(wǎng)文件互傳
這篇文章主要介紹了Python+pyftpdlib實現(xiàn)局域網(wǎng)文件互傳,需要的朋友可以參考下2020-08-08python用fsolve、leastsq對非線性方程組求解
這篇文章主要為大家詳細(xì)介紹了python用fsolve、leastsq對非線性方程組進行求解,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-12-12利用python庫在局域網(wǎng)內(nèi)傳輸文件的方法
今天小編就為大家分享一篇利用python庫在局域網(wǎng)內(nèi)傳輸文件的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06基于Python實現(xiàn)股票數(shù)據(jù)分析的可視化
在購買股票的時候,可以使用歷史數(shù)據(jù)來對當(dāng)前的股票的走勢進行預(yù)測,這就需要對股票的數(shù)據(jù)進行獲取并且進行一定的分析。本文將介紹如何通過Python實現(xiàn)股票數(shù)據(jù)分析的可視化,需要的可以參考一下2021-12-12python matplotlib如何給圖中的點加標(biāo)簽
這篇文章主要介紹了python matplotlib給圖中的點加標(biāo)簽,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11