繁体   English   中英

Python 代码从 IDE 运行,而不是从终端运行

[英]Python code runs from IDE, but not from terminal

当我尝试从 Linux 终端运行代码时,我的导入不起作用。 具体来说,从同一项目中的其他包导入。 我知道这是 PYTHONPATH 问题,但我不知道如何进一步诊断或解决它。 代码在 IDE (eclipse) 中运行良好。

我对永久解决方案感兴趣,猜测它将涉及编辑 .bashrc。 我只想从命令行调用脚本,比如

python my_script.py

os.environ["PYTHONPATH"]在 ipython 终端中给出了一个关键错误。

我试过了

print os.getcwd()
print sys.path

IDE内部

/home/myname/workspace/project2/main

['/home/myname/workspace/project2/main', '/home/myname/workspacep/problem2', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_6
4-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/p
ython2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pytho
n2.7/dist-packages/ubuntu-sso-client', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/lib-old']

航站楼内

/home/myname/workspace/project2/main

['/home/myname/workspace/project2/main', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client']

我的问题是我正在使用的 python 文件的名称,它与我正在导入的包同名并做了一个循环

Pycharm Eclipse 中执行脚本与在 bash shell 中执行脚本之间的区别在于环境变量 $PYTHONPATH 的值。

Pycharm 中,转到首选项,然后项目解释器设置并将鼠标悬停在您在终端中找不到的包上。 该包所在的路径应该显示出来。 Eclipse,找出你项目的环境变量的存储位置,或者找到有问题的模块的路径。

将该路径添加到 shell 中的 $PYTHONPATH 中

PYTHONPATH=$PYTHONPATH:your/path/here

您可以将该行添加到您的 .bashrc 或 .bash_profile 文件中,您可以将其添加到您的 bash 脚本中,或者您可以每次都输入它。

更新响应 OP 评论:

使用指向安装了您未找到的 python 模块的目录的路径。

试试

python -v

在您的 IDE 控制台中。 这应该会给你一个模块列表和它们的目录。

在你的 shell 中使用相同的命令,差异会告诉你哪里缺少什么。

如前所述,为了说明 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.path s在终端中更改,具体取决于您从何处运行它以及文件所在的位置。 但关键是sys.path s,因为它们告诉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

在子文件夹下有一个空的__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}')

以下是我尝试在终端中的projectproject/subfolder下运行 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'

可以看到,在cwdsys.path之间,直接影响我的import的是sys.path ,这取决于您的main.py的存储位置。 在项目根目录下运行main.py ,我能够按预期从根目录导入mod1和从子文件夹导入mod2 mod2copy应该会失败,因为 root 中没有mod2 然而,当执行main.py存储在子文件夹, mod1未能导入,因为蟒蛇不知道去哪里mod1存储,由于缺少sys.path 但是,如果我在import之前添加了以下行:

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仍然成功,因为subfolder在追加之前已经是sys.path列表的一部分。

尽管如此,当您有一个模块引用子结构中的另一个模块时,它会变得混乱。 说, /subfolder/module3尝试import mod2并且您正在从/project/main.py执行,当您的脚本from subfolder import mod3执行时,行import mod2将像以前一样返回ModuleNotFoundError因为sys.path不包含/project/subfolder ,因此您需要在模块之间的所有这些import一些技巧。 另一件要考虑的事情是相对路径——如果你开始移动文件,所有这些sys.path都需要维护。

总而言之 - 如果您希望导入既不在 Python 库中也不嵌套在项目根目录下的模块,那么您将陷入困境。

对于小型临时项目,例如在完成模块之前进行临时测试,上述方法是一种快速而简单的补救措施。 但是,如果您打算在未来的项目中重用这些模块,请考虑将它们存储在一个集中的路径中并添加到您的 PYTHONPATH。 此线程有更多信息,例如,如果您想将模块存储在/home/myname/modules

~/.bashrc下行添加到您的~/.bashrc

 export PYTHONPATH="${PYTHONPATH}:/home/myname/modules"

...然后在modules (包括modules本身)下创建的每个文件夹中添加一个名为__init__.py的空文件以避免导入问题。

如果您愿意做额外的工作,如上所述,您可以随时考虑将模块转换为包并通过 pip 安装它。 这样你就不必担心 PATH 处理了。

终端执行和 IDE 执行之间存在差异的原因可能是虚拟环境可能是为 IDE 配置的,但不是为终端运行代码的实际环境。 您可以通过运行以下命令来检查它:path_of_virt_env your_command。 'path_of_virt_env' 是运行代码表单 IDE 时 IDE 在控制台上显示为输出的第一个参数。 现在,要解决它,请在终端中 pip 安装所有导入的库。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM