假设我有一个任意大的模块化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
是根文件夹 - 它是一个PyCharm项目,它不是一个模块。 project\package
是项目的根Python模块。它包含许多子目录,每个子目录都是一个名为moduleN
的Python模块。 project\package\moduleN
模块都包含许多子目录,每个子目录都是一个名为submoduleN
的Python模块......依此类推。假设我有一个名为foo.py
的特定Python脚本,我想运行它,它位于package
下无限多个子模块中的一个:
# foo.py:
from package.module2.submodule3 import foo
print foo.bar()
当脚本从 PyCharm 运行Ctrl+F9
时:没问题,foo.bar()
打印。
但是当脚本从Git Bash终端运行时,从主目录运行:
python path/to/project/package/module4/submodule6/subsubmobile5/foo.py
抛出以下错误:
ImportError:没有名为package.module2.submodule3
的模块
我想知道我需要做些什么才能让我的脚本在Git Bash上运行,和为什么PyCharm和Git Bash之间首先出现差异。是否与PYTHONPATH
有关?
编辑:
sys.path.append()
黑客的一些迭代。在我的案例中,这些建议都不起作用。.bashrc
设置了export PYTHONPATH=absolute/path/to/project/package
文件,其中package
是我在PyCharm中的源根,但仍然会导致导入错误。相对路径也不起作用。我已通过echo $PYTHONPATH
验证路径是否正确。 export PYTHONPATH=absolute/path/to/project
同样不起作用。编辑2 :
问题仍未解决,但可能与Git Bash未正确设置PYTHONPATH
有关。当Add Content Roots to PYTHONPATH
未选中时,PyCharm会抛出与Git Bash相同的导入错误。
答案 0 :(得分:3)
解决问题的正确方法是不来破解PYTHONPATH
,因为如果您的库/应用程序具有第三方依赖项,这将无用。
为了正常工作,PyCharm使用了两件事:
PYTHONPATH
),和要检查,请在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并在开发/可编辑模式下安装您的应用程序:
yourvenv\Scripts\activate
cd path\to\project\
pip install -e .
在这里,您已经安装了库/应用程序及其所有依赖项。
-e
标志表示"可编辑" (符合旧版"开发"模式),
请参阅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
答案 1 :(得分:1)
注意:如果您的应用程序/库具有第三方依赖项,则下面公开的解决方案将无法正常工作。为此,您需要virtualenv。查看我的previous answer。
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
答案 2 :(得分:1)
最终,Laurent's answers帮我解决了这个问题。
我用过:
import sys
for p in sys.path:
print(p)
帮助我确定在PyCharm上添加到PYTHONPATH
与Git Bash之间确实存在差异。在PyCharm上, /path/to/project
和/path/to/project/package
都被添加到PYTHONPATH
。在Git Bash上,只添加了一个。
因此,我修改了export
中的.bashrc
语句,以便将两条路径追加到PYTHONPATH
;即来自:
export PYTHONPATH="${PYTHONPATH}:absolute/path/to/project/package"
到:
export PYTHONPATH="${PYTHONPATH}:absolute/path/to/project:absolute/path/to/project/package"
然后解决了导入错误。 1 同样,当PATH
AND PYTHONPATH
用户环境变量被类似地声明时,脚本在Windows命令提示符下按预期工作
我最好的猜测是将PyCharm中的Sources Root设置为项目目录以外的其他内容可能需要多次添加PYTHONPATH
。
1在网站上注意:我的脚本随后开始无限期挂起,通过别名Python解析:alias python="winpty python"
。
修改强>
Git Bash在MinGW64下运行 - export
语句中的Windows路径列表在被Python的导入解析处理之前受Posix path conversion的约束。
从技术上讲,export PYTHONPATH="absolute/path/to/project;absolute/path/to/project/package"
应正确解析为两条路径。