简体   繁体   English

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

[英]Python script runs in PyCharm but not Git Bash

Say I've got a arbitrarily big, modular Python 2.7 codebase: 假设我有一个任意大的模块化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
  • project is the root folder - it's a PyCharm project and it's not a module. project是根文件夹-它是一个PyCharm项目,而不是一个模块。
  • project\\package is the root Python module for the project. project\\packageproject\\package的根Python模块。 It contains many subdirectories, each of which is a Python module named moduleN . 它包含许多子目录,每个子目录都是一个名为moduleN的Python模块。
  • Each project\\package\\moduleN module contains many subdirectories, each of which is a Python module named submoduleN ... and so on and so forth. 每个project\\package\\moduleN模块都包含许多子目录,每个子目录都是一个名为submoduleN ...的Python模块,依此类推。

Say I have a particular Python script called foo.py that I would like to run, and it's located within one of the infinitely many submodules under package : 假设我有一个要运行的特定Python脚本foo.py ,它位于package下的无限多个子模块之一中:

# foo.py:

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

When the script is ran from PyCharm with Ctrl+F9 : no problem, foo.bar() prints. 当使用Ctrl+F9PyCharm运行脚本时:没问题, foo.bar()打印foo.bar()

But when the script is ran from the Git Bash terminal, from the home directory, with: 但是,当从Git Bash终端从主目录运行脚本时,使用以下命令:

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

The following error is thrown: 引发以下错误:

ImportError: No module named package.module2.submodule3 ImportError:没有名为package.module2.submodule3的模块


I would like to know what I need to do in order to get my script to run on Git Bash, and why there is a discrepancy in the first place between PyCharm and Git Bash. 我想知道我需要做些什么才能使我的脚本在Git Bash上运行, 以及为什么在PyCharm和Git Bash之间首先存在差异。 Is it something to do with PYTHONPATH ? PYTHONPATH吗?


EDIT : 编辑

  • Many StackOverflow answers suggest using some iteration of sys.path.append() hacks. 许多 StackOverflow答案建议使用sys.path.append() hack的一些迭代。 None of these suggestions work in my case. 这些建议对我来说都不起作用。
  • I set up a .bashrc file with export PYTHONPATH=absolute/path/to/project/package , where package is my source root in PyCharm, but the import error is still thrown. 我用export PYTHONPATH=absolute/path/to/project/package设置了.bashrc文件,其中package是我在PyCharm中的源根目录,但是仍然抛出导入错误。 Relative paths do not work either. 相对路径也不起作用。 I have verified that the paths are correct with echo $PYTHONPATH . 我已经用echo $PYTHONPATH验证了路径是正确的。 export PYTHONPATH=absolute/path/to/project similarly does not work. export PYTHONPATH=absolute/path/to/project同样不起作用。
  • The working directory doesn't seem to matter - Git Bash fails every time regardless of the working directory and PyCharm works every time regardless of the working directory. 工作目录似乎无关紧要-无论工作目录如何,Git Bash每次都会失败,而无论工作目录如何,PyCharm都会每次工作。

EDIT 2 : 编辑2

The issue is still unresolved but it may have to do with PYTHONPATH not being set correctly on Git Bash. 该问题仍未解决,但可能与在Git Bash上未正确设置PYTHONPATH有关。 When Add Content Roots to PYTHONPATH is unticked , PyCharm throws the same import error as Git Bash. 取消选中 Add Content Roots to PYTHONPATH 目录时 ,PyCharm会引发与Git Bash相同的导入错误。

The right way to solve your problem is not to hack the PYTHONPATH , because this won't be useful if your library/application has third-party dependencies. 解决问题的正确方法是不要破解PYTHONPATH ,因为如果您的库/应用程序具有第三方依赖项,这将无用。

To work properly, PyCharm used two things: 为了正常工作,PyCharm使用了两件事:

  • the Source Root (which is added to the PYTHONPATH ), and, 源根(添加到PYTHONPATH ),并且,
  • the Project Interpreter (ie the virtualenv), 项目解释器(即virtualenv),

To check that, open a Terminal view in PyCharm, and try: 要进行检查,请在PyCharm中打开终端视图,然后尝试:

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

The right way is using a virtualenv . 正确的方法是使用virtualenv

To create a virtualenv on Windows, go to a directory where you want to create a virtualenv. 要在Windows上创建virtualenv,请转到要在其中创建virtualenv的目录。 It can be in a unique directory (like recommended by pew ), or in your project directory (usually in .venv ). 它可以位于唯一目录(如pew推荐)中,也可以位于项目目录中(通常在.venv )。

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

Then, activate your virtualenv and install your application in development/editable mode: 然后,激活您的virtualenv并以开发/可编辑模式安装您的应用程序:

yourvenv\Scripts\activate

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

Here, you have installed your library/application with all its dependencies. 在这里,您已经安装了具有所有依赖项的库/应用程序。 The -e flag means "editable" (which match the old "develop" mode), See pip documentation for that. -e标志的意思是“可编辑”(与旧的“开发”模式匹配),有关该信息,请参见pip文档。

Whenever you want to run a script, you can do as follow: 每当您要运行脚本时,都可以执行以下操作:

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

On Windows, you can also do: 在Windows上,您还可以执行以下操作:

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

On Git bash, you do: 在Git bash上,您可以执行以下操作:

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

If you want to call your Python script from another batch, you can do: 如果要从另一批调用Python脚本,则可以执行以下操作:

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

Notice: the solution exposed below won't work if your application/library has third-party dependencies. 注意:如果您的应用程序/库具有第三方依赖项,则下面提供的解决方案将不起作用。 For that, you need a virtualenv . 为此,您需要一个virtualenv See my previous answer . 看到我以前的答案

You have the following tree structure in path\\to\\project : 您在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

Here, package is the root Python package of your project, and path\\to\\project is your project source directory (the one that PyCharm use). 在这里, package是项目的根Python软件包, path\\to\\project是项目的源目录(PyCharm使用的目录)。

To run a script in this packages, for instance the script package/module4/submodule6/subsubmobile5/foo.py , you need to set the PYTHONPATH to the root of the project, ie path\\to\\project . 要在此程序包中运行脚本,例如脚本package/module4/submodule6/subsubmobile5/foo.py ,您需要将PYTHONPATH设置为项目的根目录,即path\\to\\project

But, since you are on Windows and run Git Bash, you need to convert the Windows path to a valid Linux path, with forward slash. 但是,由于您在Windows上并运行Git Bash,因此需要将Windows路径转换为有效的Linux路径,并使用正斜杠。

One way to do that is as follow: 一种方法如下:

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

You can even execute the module package.module4.submodule6.subsubmobile5.foo : 您甚至可以执行模块package.module4.submodule6.subsubmobile5.foo

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

Ultimately, Laurent's answers helped me figure this out. 最终, 洛朗的 答案帮助我弄清楚了这一点。

I used: 我用了:

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

to help me determine that there was indeed a discrepancy between what's being added to PYTHONPATH on PyCharm versus Git Bash. 以帮助我确定在PyCharm和Git Bash上添加到PYTHONPATH内容之间确实存在差异。 On PyCharm, both /path/to/project and /path/to/project/package are being added to PYTHONPATH . 在PyCharm, 无论 /path/to/project/path/to/project/package被添加到PYTHONPATH On Git Bash, only one is being added. 在Git Bash上,仅添加了一个。

So I modified my export statement in .bashrc such that it appends both paths to PYTHONPATH ; 因此,我在.bashrc修改了我的export语句,以便将两个路径都附加到PYTHONPATH ie from: 即来自:

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

to: 至:

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

The import error was then resolved. 然后解决了导入错误。 1 Similarly, the script works as-intended on the Windows command prompt when the PATH AND PYTHONPATH user environmental variables are similarly declared. 1同样,当类似地声明PATHPYTHONPATH用户环境变量时,脚本将按预期在Windows命令提示符下工作。

My best guess is that setting the Sources Root in PyCharm to something other than the project directory may require multiple additions to PYTHONPATH . 我最好的猜测是将PyCharm中的Sources Root设置为项目目录以外的其他内容可能需要对PYTHONPATH进行多次添加。

1 On a site note: my script then started hanging indefinitely which was resolved by way of aliasing Python: alias python="winpty python" . 1在站点注释上:然后我的脚本无限期地开始挂起,这通过使用别名Python来解决: alias python="winpty python"

EDIT: 编辑:

Git Bash operates under MinGW64 - where lists of Windows paths in export statements are subject to Posix path conversion prior to being processed by Python's import resolution. Git Bash在MinGW64下运行- export语句中的Windows路径列表在经过Python的导入解析处理之前必须经过Posix路径转换

So technically, export PYTHONPATH="absolute/path/to/project;absolute/path/to/project/package" should correctly resolve to two paths. 因此,从技术上讲, export PYTHONPATH="absolute/path/to/project;absolute/path/to/project/package"应该正确解析为两个路径。

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

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