最近在學習別人寫的程序,有位大神把其他經典算法都實現了,baseline包全弄好了,我真是興沖沖,提起袖子膜拜大神,沒想到環境都build好了,在引自己的各種模塊時頻頻報錯,深知是引用的問題,Google了半天都沒弄好,最後經過耐心探索
解決方案
先把出現報錯的解決方案放在前面:
檢查哪種錯誤:
ValueError: Attempted relative import in non-package
說明存在相對導入語句的模塊,不能直接運行,把相對導入改成絕對引用。
No module named ‘…’
說明路徑不對,找不到模塊。
如果是絕對導入,一個模塊只能導入自身的子模塊或和它的頂層模塊同級別的模塊及其子模塊
如果是相對導入,一個模塊必須有包結構且只能導入它的頂層模塊內部的模塊
- 找不到模塊時,先看看有沒有
__init__.py
文件在該包裏,告訴導入指令我包在這。 - 如果要把相對導入改爲絕對導入,
from __future__ import absolute_import
(僅禁用隱式相對導入),Python2.x 缺省爲相對路徑導入,Python3.x 缺省爲絕對路徑導入。 - 萬能法。直接把該文件夾看作一個workspace,路徑加入環境變量中。(這裏考慮加入用戶的環境變量,而不是全局的系統變量),在用戶home路徑下可以看是否有這個隱藏文件
ls -a
,~表示用戶home目錄。
vim ~/.bash_profile
進入vim編輯器,隨意i\o\a進入編輯模式
export PYTHONPATH=</home/user/ALL>:$PATH
這裏的<>替換成該文件夾地址,然後加上:$PATH表示這個PATH爲該地址再加上原來路徑,最後不要加/。
source ~/.bash_profile
原理是會在PYTHONPATH的List依次搜索,如果在前面搜到就用前面的模塊,而不會繼續向下,這樣自定義模塊優先。 - 治標不治本法1。在代碼裏將當前模塊路徑加入,腳本退出失效。
import sys
sys.path.append('/home/user/ALL/')
- 治標不治本法2。直接
export PYTHONPATH=</home/user/ALL>:$PATH
,但是終端關閉就失效。
import的搜索路徑
導入分爲相對導入和絕對導入,而這個導入是有原則的。
- 在當前目錄下搜索import的模塊
- 在環境變量PYTHONPATH的List依次搜索
- 在python安裝路徑的lib裏搜索
相對導入和絕對導入
相對是對於當前目錄而言的,先牢記.
代表當前模塊,..
代表上層模塊,...
代表上上層模塊,比如以下結構:
ALL
|___A
| |___Z
| |___util.py
| |___init.py
|___B
| |__check.py
|___C
| |___result.py
|___setup.py
A B C
文件夾和setup.py
文件都在ALL
裏Z
在A
裏,util.py
和init.py
在Z
裏check.py
在B
裏resul.py
在C
裏
這一篇寫得很詳細Python 相對導入與絕對導入。
相對導入
- 在
util.py
裏導入init.py
可以寫爲import init
(不用加.
因爲會先在當前目錄下搜索)from . import init
from Z import init
- 在
util.py
裏導入check.py
可以寫爲from ..B import check
絕對導入
- 在
util.py
裏導入init.py
寫爲import ALL.A.Z imprort init
- 在
util.py
裏導入check.py
可以寫爲from ALL.B import check
-
- 在
util.py
裏導入setup.py
可以寫爲from ALL import check
- 在