Python 脚本在 PyCharm 中运行但不在 Git Bash 中运行

Python script runs in PyCharm but not Git Bash

假设我有一个任意大的模块化 Python 2.7 代码库:

project
↳ docs
↳ etc
↳ package
  ↳ module1
    ↳ submodule1
      ↳ subsubmodule1
        ↳ __init__.py
      ↳ subsubmodule2 (... and so on)
      ↳ __init__.py
    ↳ submodule2
      ↳ subsubmodule1
        ↳ __init__.py
      ↳ subsubmodule2 (... and so on)
      ↳ __init__.py
    ↳ submodule3 (... and so on)
      ↳ __init__.py
  ↳ module2
    ↳ submodule1
      ↳ __init__.py
    ↳ submodule2 (... and so on)
      ↳ __init__.py
    ↳ __init__.py        
  ↳ module3 (... and so on)
    ↳ __init__.py
  ↳ __init__.py
↳ test

假设我有一个名为 foo.py 的特定 Python 脚本,我想 运行,它位于 package 下的无限多个子模块之一中:

# foo.py:

from package.module2.submodule3 import foo
print foo.bar()

当脚本是 运行 来自 PyCharmCtrl+F9 时:没问题,foo.bar() 打印。

但是当脚本是 运行 来自 Git Bash 终端,来自主目录,带有:

python path/to/project/package/module4/submodule6/subsubmobile5/foo.py

抛出以下错误:

ImportError: No module named package.module2.submodule3


我想知道我需要做什么才能让我的脚本在 Git Bash、 上达到 运行为什么 PyCharm 和 Git Bash 之间首先存在差异。跟PYTHONPATH有关系吗?


编辑

编辑 2:

问题仍未解决,但可能与 PYTHONPATH 在 Git Bash 上的设置不正确有关。当 Add Content Roots to PYTHONPATH 未勾选 ,PyCharm 抛出与 Git Bash.

相同的导入错误

解决问题的正确方法是而不是破解PYTHONPATH,因为如果你的library/application有第三个-党的依赖。

为了正常工作,PyCharm 使用了两个东西:

  • 源根(添加到 PYTHONPATH),并且,
  • 项目解释器(即 virtualenv),

要检查这一点,请在 PyCharm 中打开终端视图,然后尝试:

$ python
>>> import sys
>>> for p in sys.path:
...     print(p)
...

正确的方法是使用 virtualenv

要在 Windows 上创建 virtualenv,请转到要创建 virtualenv 的目录。 它可以在一个独特的目录中(如 pew 推荐的那样), 或在您的项目目录中(通常在 .venv)。

virtualenv -p C:\Python27\python.exe yourvenv

然后,激活您的 virtualenv 并在 development/editable 模式下安装您的应用程序:

yourvenv\Scripts\activate

cd path\to\project\
pip install -e .

在这里,您已经安装了 library/application 及其所有依赖项。 -e 标志表示 "editable" (匹配旧的 "develop" 模式), 请参阅 pip 文档。

任何时候你想运行一个脚本,你可以按如下方式做:

yourvenv\Scripts\activate
python -m package.module4.submodule6.subsubmobile5.foo

在 Windows 上,您还可以:

yourvenv\Scripts\activate
python path\to\project\package\module4\submodule6\subsubmobile5\foo.py

在 Git bash,你做了:

source yourvenv/Scripts/activate
python path/to/project/package/module4/submodule6/subsubmobile5/foo.py

如果你想从另一个批次调用你的 Python 脚本,你可以这样做:

yourvenv/Scripts/python.exe -m package.module4.submodule6.subsubmobile5.foo
yourvenv/Scripts/python.exe path/to/project/package/module4/submodule6/subsubmobile5/foo.py

注意:如果您的 application/library 有第三方依赖项,下面公开的解决方案将不起作用。为此,您需要 virtualenv. See my .

您在 path\to\project 中具有以下树结构:

path\to\project
├───docs
├───etc
├───package
│   │   __init__.py
│   ├───module1 [...]
│   ├───module2
│   │   │   __init__.py
│   │   ├───submodule1 [...]
│   │   ├───submodule2 [...]
│   │   └───submodule3
│   │           foo.py
│   │           __init__.py
│   ├───module3 [...]
│   └───module4
│       │   __init__.py
│       └───submodule6
│           │   __init__.py
│           └───subsubmobile5
│                   foo.py
│                   __init__.py
└───tests

这里,package是你项目的根Python包,path\to\project是你的项目源目录(PyCharm使用的那个)。

对于运行这个包中的脚本,例如脚本package/module4/submodule6/subsubmobile5/foo.py,你需要将PYTHONPATH设置为项目的根目录,即path\to\project .

但是,由于您在 Windows 和 运行 Git Bash 上,您需要将 Windows 路径转换为有效的 Linux 路径,带正斜杠。

一种方法如下:

$ export PYTHONPATH=path/to/project && python path/to/project/package/module4/submodule6/subsubmobile5/foo.py

你甚至可以执行模块 package.module4.submodule6.subsubmobile5.foo:

$ export PYTHONPATH=path/to/project && python -m package.module4.submodule6.subsubmobile5.foo

最终, 帮我解决了这个问题。

我用过:

    import sys
    for p in sys.path:
        print(p)

帮助我确定 PyCharm 上添加到 PYTHONPATH 的内容与 Git Bash 中添加的内容之间确实存在差异。在 PyCharm 上, /path/to/project/path/to/project/package 都被添加到 PYTHONPATH。在 Git Bash 上,只添加了一个。

所以我在 .bashrc 中修改了我的 export 语句,以便将两个路径附加到 PYTHONPATH;即来自:

export PYTHONPATH="${PYTHONPATH}:absolute/path/to/project/package"

至:

export PYTHONPATH="${PYTHONPATH}:absolute/path/to/project:absolute/path/to/project/package"

导入错误随后得到解决。1 同样,当 PATHPYTHONPATH 用户环境变量声明类似。

我最好的猜测是将 PyCharm 中的 Sources Root 设置为项目目录以外的其他内容可能需要向 PYTHONPATH.

添加多个内容

1 在站点注释上:我的脚本然后开始无限期挂起,这是通过别名 Python 解决的:alias python="winpty python".

编辑:

Git Bash 在 MinGW64 下运行 - 其中 export 语句中的 Windows 路径列表在被 [= 处理之前受制于 Posix path conversion 62=]的导入分辨率。

所以从技术上讲,export PYTHONPATH="absolute/path/to/project;absolute/path/to/project/package" 应该正确解析为两条路径。