問題簡單描述:
一般我們在pycharm中run程序的時候,會將當前工程的所有文件夾路徑都作為包的搜索路徑;而在命令行中運行‘xxx.py’時,或者sh腳本文件運行‘xxx.py’時,只是搜索當前路徑,就會找不到module
粗暴解決辦法:
在要運行的‘xxx.py’最前面加上以下代碼:
import sys,os curPath = os.path.abspath(os.path.dirname(__file__)) rootPath = os.path.split(curPath)[0] sys.path.append(rootPath)
具體原因(轉載於:https://blog.csdn.net/qq_36829091/article/details/82180866)
問題
項目結構如下:
- 整個項目名為project
- package1和package2是項目文件夾下的兩個文件夾,即兩個包(package)
- 兩個包中分別有__init__.py 和 module1.py / module2.py文件,其中module1.py和module2.py文件為兩個模塊(module)
(在python中一個文件可以被看成一個獨立模塊,而包對應着文件夾。區別包和文件夾的重要特征就是包文件夾內每一層目錄都有初始化文件__init__.py
)
module1.py中為:
def print_a(a):
print(a)
module2.py中為:(引入了package1中的module1,module2和module1不在同一包下。程序輸出為打印hello world)
from package1 import module1 module1.print_a('hello world')
在Pycharm或IPython之類的IDE上運行腳本正常:
但在pycharm的終端(terminal)或cmd命令行執行python module2.py命令,報了模塊未能找到的錯誤:
原因:(不想看可直接跳到解決方法)
Python在啟動解釋器(Interpreter)時不光會導入環境變量中sys.path
發現的模塊,還會導入當前工作目錄下的模塊。
什么是環境變量中sys.path
發現的模塊和當前工作目錄下的模塊?
在module2.py開頭加上2行代碼:
import sys print(sys.path) from package1 import module1 module1.print_a('hello world')
使用 python module2.py 命令在終端運行,得到
紅框中的第一個綠線位置就是當前工作目錄下的模塊,后面的幾個則是環境變量中sys.path原本發現的模塊。
當你在IDE中啟動解釋器時,當前的工作目錄就是項目目錄,能順利調用同項目中的模塊;但是當你通過命令行啟動時,當前工作目錄為你啟動解釋器時所在的目錄,如果當時的位置不是項目目錄,那么項目目錄中的模塊就不會被找到,因此運行的時候報錯:ModuleNotFoundError: No Module named ...(在例子中我的當前目錄是.../package2是項目目錄底下的一個文件夾,不是項目目錄,所以報錯)
解決方法:
方法很簡單,就是把模塊路徑提供給解釋器:
(推薦) 把模塊路徑放到環境變量中作為全局變量(sys.path能掃描到)。
在module2.py開頭加入sys.path.append('../'):
import sys sys.path.append('../') # 新加入的 print(sys.path) from package1 import module1 module1.print_a('hello world')
sys.path.append()中添加的正是這個項目的項目目錄('../'表示當前目錄的父目錄,也即這個項目的項目目錄)
隨后打印出的結果為:
綠色一行為當前目錄,黃色一行為新添加的項目目錄。這樣就不會再報錯了。
或者使用指向項目目錄(project)的絕對路徑:sys.path.append('D:\\coding\\deep_learning\\adversarial_example\\project'):
import sys sys.path.append('D:\\coding\\deep_learning\\adversarial_example\\project') print(sys.path) from package1 import module1 module1.print_a('hello world')
輸出: