如上所述,为了说明IDE执行和终端执行期间使用的路径的不同,请在IDE和终端中运行以下脚本:
import os
import sys
print(os.getcwd())
for i in sys.path:
print(i)
比较结果,从终端执行时,与在IDE中运行相比,这些文件夹丢失了:
'/home/myname/workspacep/problem2'
'/usr/lib/pymodules/python2.7'
需要注意的是,当前工作目录和sys.paths将在终端中更改,具体取决于您从哪里运行以及文件所在的位置.但关键是sys.paths,因为它们告诉python在哪里寻找模块.
我愿意打赌你试图导入的模块来自其中一个文件夹,很可能是在/ home / myname / workspacep / problem2下.这会引入问题,因为您的模块既不存储在集中访问位置(例如/usr/lib/python2.7/my_modules),也不存储在项目结构下的子文件夹中.
为了说明,我有一个模拟项目文件夹设置如下:
pi@box:~/project $tree
.
├── main.py
├── mod1.py
└── subfolder
├── __init__.py
├── main.py
└── mod2.py
在子文件夹see here for more details下有一个空的__init__.py是个好主意.我的main.py看起来像这样:
import os
import sys
print(f'cwd = {os.getcwd()}')
print(f'path0 = {sys.path[0]}')
try:
import mod1
mod1.hello()
except Exception as e:
print(f'import mod1 failed: {e}')
try:
from subfolder import mod2
mod2.hello()
except Exception as e:
print(f'from subfolder import mod2 failed: {e}')
try:
import mod2 as mod2copy
mod2copy.hello()
except Exception as e:
print(f'import mod2copy failed: {e}')
下面是我尝试在终端中的项目和项目/子文件夹下运行main.py时的执行结果:
pi@box:~/project $python3 main.py
cwd = /home/pi/project
path0 = /home/pi/project
Module 1 reporting in!
Module 2 reporting in!
import mod2copy failed: No module named 'mod2'
pi@box:~/project $python3 ./subfolder/main.py
cwd = /home/pi/project
path0 = /home/pi/project/subfolder
import mod1 failed: No module named 'mod1'
from subfolder import mod2 failed: No module named 'subfolder'
Module 2 reporting in!
pi@box:~/project $cd subfolder
pi@box:~/project/subfolder $python3 main.py
cwd = /home/pi/project/subfolder
path0 = /home/pi/project/subfolder
import mod1 failed: No module named 'mod1'
from subfolder import mod2 failed: No module named 'subfolder'
Module 2 reporting in!
pi@box:~/project/subfolder $python3 ../main.py
cwd = /home/pi/project/subfolder
path0 = /home/pi/project
Module 1 reporting in!
Module 2 reporting in!
import mod2copy failed: No module named 'mod2'
您可以在cwd和sys.path之间看到,sys.path直接影响我的导入,这取决于main.py的存储位置.在项目根目录下运行main.py时,我能够按照预期从root用户导入mod1和从子文件夹导入mod2. mod2copy应该失败,因为root中没有mod2.但是,当执行存储在子文件夹中的main.py时,mod1导入失败,因为python不知道mod1的存储位置,因为缺少sys.path.但是,如果我在导入之前添加了以下行:
sys.path.append('/home/pi/project')
子文件夹下的main.py的结果将变为:
pi@rpirpirpi:~/project/subfolder $python3 main.py
cwd = /home/pi/project/subfolder
path0 = /home/pi/project/subfolder
Module 1 reporting in!
Module 2 reporting in!
Module 2 reporting in!
你会注意到所有3个进口都是成功的. Python能够找到mod1和/ subfolder / mod2,因为根路径现在已添加到脚本的sys.path中.并且mod2copy仍然成功,因为子文件夹在附加之前已经是sys.path列表的一部分.
总而言之,当你有一个模块引用子结构中的另一个模块时,它会变得混乱.比如,/ subfolder / module3尝试导入mod2并且你正在从/project/main.py执行,当你从子文件夹import mod3执行脚本时,行import mod2会像以前一样返回ModuleNotFoundError,因为sys.path不包含/ project / subfolder,所以你需要在模块之间的所有这些导入中有一些技巧.另一件需要考虑的事情是相对路径 – 如果你开始移动文件,那么所有这些sys.path都需要维护.
总结一下 – 如果您希望导入既不在Python库中也不嵌套在项目根目录下的模块,那么您将陷入困境.
以上是针对小型临时项目的快速简便的补救措施,比如,在最终确定模块之前进行临时测试.但是,如果您打算在将来的项目中重用这些模块,请考虑将它们存储在集中路径中并添加到PYTHONPATH中. This thread have some more information,,例如,如果要将模块存储在/ home / myname / modules下:
add the below line to your ~/.bashrc:
06007
… and then add an empty file named __init__.py in each folder created under modules (including modules itself) to avoid import issues.
如果您需要额外的工作,如上所述,您可以随时查看将模块转换为包并通过pip安装.这样您根本不必担心PATH处理.