OutLine
Pycharm 中完成編碼,且在 Pycharm 中可正常運行,以為就萬事大吉了,但在Linux命令行中執行時,報錯:找不到所導入的包;
先看下目錄結構:
- from scripts import * 我在 scripts/__init__.py 中寫了一個基類,供后續繼承使用
- dump_factor.py 執行的py文件
- 在 dump_factor.py 中也 sys.path.append 添加了環境變量(把項目根目錄添加到環境變量)
網上各種類似問題,也都可以通過 sys.path.append 添加環境變量解決,理論上我這個也可以這么解決;
但添加環境變量后,依然報錯,提示找不到包;
因此進行debug定位下問題,並且記錄下;
報錯示例:
Python導入模塊的搜索順序(原理)
python 解釋器查找包(模塊)的順序:
- 內存(模塊緩存)
- 內置模塊 built-in module(例如:sys、os, 可通過sys.builtin_module_names查看)
- sys.path (環境變量中)
sys.path 列表中 index:0 (第一個元素),為被執行python文件所在目錄,優先級最高 - 標准庫 (可通過sys.modules查看)
- .pth 文件(python會尋找.pth文件,然后將文件里路徑加入 sys.path)
- 第三方庫(你pip install的庫)
內置模塊:
sys.path:
標准庫:
問題分析
查看當前 sys.path 環境變量中是否有所需路徑
上圖是我 sys.path.append() 后的環境變量列表;
可以看到:
/home/mdlib/git_pro/mj-data-sdk/scripts/dump_factor (被執行py文件所在目錄)
/home/mdlib/git_pro/mj-data-sdk (項目根目錄)
<項目根目錄、被執行py文件所在目錄> 都有了,按理說python會去遍歷 sys.path 列表,肯定能找到對應環境變量(因為我已經append進去了);
但實際執行時,依然提示找不到模塊。
問題解決
因為 sys.path 列表中 index:0 位置,是被執行python文件所在目錄,優先級最高,會第一個找這個目錄;
而我append進去的項目根目錄 </home/mdlib/git_pro/mj-data-sdk>,在最后面
沒等找到它,就先遇到了 /home/mdlib/git_pro/mj-data-sdk/scripts/dump_factor (被執行py文件所在目錄),就直接用了
從目錄結構來看,/home/mdlib/git_pro/mj-data-sdk/scripts/dump_factor 下面是沒有 scripts 的,自然沒法導入scripts,就會找不到報錯;
但在項目根目錄視角下,就有scripts了,就可以導入了;
所以,就當前情況而言,sys.path 中 index:0 位置的路徑,應該是項目根目錄:
這么操作即可
import sys import os curPath = os.path.abspath(os.path.dirname(__file__)) rootPath = os.path.split(curPath)[0] sys.path.insert(0, os.path.split(rootPath)[0])
把項目根目錄 insert 到 sys.path 列表第一個元素,python找的時候就會先找到 項目根目錄。
總結
當你在pycharm中完成編碼,執行代碼時,pycharm會動態幫你把一切都做好,基本不會出現類似導包出錯問題;
但在命令行情況下,就需要注意是否存在該問題了;