如何正确设置 Visual Studio Code 的 PYTHONPATH

132
我应该如何在Visual Studio Code工作区中正确设置$PYTHONPATH变量?
背景信息:
我安装了两个版本的GNURadio:
1.由Linux Mint软件包管理器安装的GNURadio 3.7.11,位于/usr/lib/python2.7/dist-packages/gnuradio。
2.PyBOMBS安装的GNURadio 3.7.13.4,位于/home/tejul/Documents/gr13/default/lib/python2.7/dist-packages/gnuradio(我的前缀目录是~/Documents/gr13/default)。
只有在运行setup_env.sh脚本(其中之一是将/home/tejul/Documents/gr13/default/lib/python2.7/dist-packages添加到$PYTHONPATH中)并在终端中启动python后,我才能使用更新的GNURadio版本。
tejul@Wacom:~/Documents/gr13/default$ ls
bin  etc  include  lib  libexec  setup_env.sh  share  src
tejul@Wacom:~/Documents/gr13/default$ source ./setup_env.sh 
tejul@Wacom:~/Documents/gr13/default$ python
Python 2.7.15rc1 (default, Nov 12 2018, 14:31:15) 
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from gnuradio import gr
>>> gr.version()
'3.7.13.4'
>>> 

如果不修改$PYTHONPATH,Python会自然地导入旧版本的GNURadio。

我想在Visual Studio Code中编写、运行和调试新版本GNURadio的Python脚本。我一直在尝试理解VSCode对Python解释器工作区环境的选择。

据我所知,VSCode工作区设置python.pythonPath不应与环境变量$PYTHONPATH混淆。 python.pythonPath是用于调试或运行代码的Python解释器的路径,而$PYTHONPATH是Python用来搜索模块的环境变量。

看起来PyBOMBS没有将自己的Python解释器安装到我的前缀目录中。因此,我需要使用位于/usr/bin/python2.7的普通Python解释器来使用VSCode。因此,重新定义VSCode的python.pythonPath或选择另一个Python解释器都无法帮助我。

我需要让VSCode使用我自己版本的环境变量$PYTHONPATH,这将告诉我的常规Python解释器最好从/home/tejul/Documents/gr13/default/lib/python2.7/dist-packages中导入模块。

问题

根据文档,我已经在工作区目录中创建了自己的.env文件,设置了Python导入模块时位置的优先顺序。但是,它对Python解释器没有影响。

Showing that VSCode is ignoring my $PYTHONPATH setting

你能看到我在这里做错了什么吗?我还尝试过:

  • 将PYTHONPATH设置为更高的一个文件夹级别,即 /home/tejul/Documents/gr13/default/lib/python2.7,但这没有帮助
  • 将变量命名为$PYTHONPATH而不是PYTHONPATH,但这没有帮助
  • 在每次更改.env文件后重新启动VSCode,但这没有帮助
  • 在路径字符串周围使用双引号,例如PYTHONPATH="/home/tejul/Documents/gr13/default/lib/python2.7:/usr/lib/python2.7",但这没有帮助

我没有成功在Visual Studio Code中设置PYTHONPATH,但我已经找到了如何让VSCode从系统环境变量中继承它。我已经将以下两行添加到我的.bashrc文件中:# 设置python gnuradio环境源 /home/tejul/Documents/gr13/default/setup_env.sh这会自动为每个终端窗口运行setup_env.sh脚本。 - fleetingbytes
13个回答

150

我有一个情况,我相信它是比较常见的。我想要一个脚本从另一个目录导入模块。我的 Python 项目布局如下:

~/project/
  |
  |---modules/
        |
        |---mod.py
  |---scripts/
        |---script.py

script.py中,我使用了from modules import mod。因此,我的PYTHONPATH需要设置为~/project/(这是PyCharm自动完成的)。

VSCode是一个很棒的编辑器,但在我看来,在其他方面它表现不佳,这是一个完美的例子。

我创建了一个默认的launch.json文件来“运行当前文件”。必须添加一行"cwd": "${fileDirname}"以使其像在PyCharm中一样工作(顺便说一下,在这里可以找到内置变量列表)。

调试

对于调试(侧边栏上的“播放”按钮或F5键),在launch.json或您的.env文件中设置的PYTHONPATH会生效。请注意,在.env文件中,您不能使用诸如${workspaceRoot}之类的变量,但是您可以使用适合您平台的正确分隔符(;用于Windows,:用于其他人)轻松地附加或插入路径。

因为我想利用这个变量,所以我把这个放在我的launch.json中:

    "env": {"PYTHONPATH": "${workspaceFolder}${pathSeparator}${env:PYTHONPATH}"}

(感谢@someonr建议使用${pathSeparator}。)

看起来你可以将环境继承的任何内容前缀/后缀(对于settings.json不适用;请参见下文)。 这也适用于热键Ctrl + F5(无调试运行)。 供参考,这里是完整的文件,复制了PyCharm自动执行的操作:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "cwd": "${fileDirname}",
            "env": {"PYTHONPATH": "${workspaceFolder}${pathSeparator}${env:PYTHONPATH}"}
        }
    ]
}

在终端中运行

如果我点击编辑器窗口右上角出现的“播放”按钮(当 Python 文件是活动选项卡时),它不会起作用。这会在终端中运行当前文件,根本不关心 launch.json。要使其起作用,您必须在 settings.json 文件中定义 PYTHONPATH,并添加以下内容:

    "terminal.integrated.env.osx": {"PYTHONPATH": "${workspaceFolder}"}

(请注意,每个平台的值可能不同。)如果您选择了Python解释器(例如来自虚拟环境),则在.vscode目录中已经有一个settings.json文件。我的看起来像这样:

(Note there are different values for each platform.) 如果您选择了 Python 解释器(例如从虚拟环境中),则您已经有一个位于 .vscode 目录下的 settings.json 文件。我的文件如下所示:

{
    "python.pythonPath": "/Users/me/project/venv/bin/python3",
    "terminal.integrated.env.osx": {"PYTHONPATH": "${workspaceFolder}"}
}

您无法通过settings.json文件将值附加或插入到继承的PYTHONPATH中。它只会接受一个字符串,而且不会解析分隔符。因此,即使您可以使用${env:PYTHONPATH}获取该值,但您不能对其进行任何操作。

此外,您无法设置当前工作目录。即使您似乎可以使用"terminal.integrated.cwd": "${workspaceFolder}"来设置它,但它不起作用。因此,如果您的任何脚本使用相对于树中位置的路径执行任何操作,它们将无法正常工作。工作目录将是您的项目根目录。

请注意,对settings.json文件的任何更改都需要您退出终端并重新启动它。

代码检查

无论我在launch.json方面做了什么关于PYTHONPATH的事情,都不会对pylint产生任何影响,它仍会在from modules import mod处显示红色下划线,尽管我可以把光标放在mod上,按F12,文件就会打开。在检查设置周围嗅探时,mypy的默认值包括--ignore-missing-imports。要使用pylint复制此行为,请将其添加到您的settings.json中:

    "python.linting.pylintArgs": [
        "--disable=F0401"
    ] 

遗憾的是,我们只能绕过这个问题,但在编写导入语句时,自动完成功能确实有很大帮助。

结论

VSCode有许多层次,很难使它们协同工作。似乎有多个环境同时存在。最后:

  1. 我无法在终端中运行,因为我无法将当前工作目录设置为包含当前文件的路径。
  2. 我无法为pylint设置PYTHONPATH,因为它运行于与集成终端和由launch.json控制的任何内容不同的环境中,所以我只能告诉pylint忽略导入错误。
  3. 如果您通过.env文件或launch.json设置PYTHONPATH,则可以使用F5运行。

3
非常感谢您的帮助。我可以进行调试,但是无法理解为什么从终端运行会出现“ModuleNotFoundError”的错误。您是否有任何线索,关于VScode何时能够在这些设置下正常运行? - Imad
还有运行笔记本(和iPython),这似乎是另一个配置任务。 - mherzog
在 launch.json 中添加以下内容:"env": {"PYTHONPATH": "${workspaceFolder}${pathSeparator}${env:PYTHONPATH}"},这个设置在 Win11-VSCode 上对我有效。 - terwxqian
6
@someone ${pathSeparator} 不是 :;${pathSeparator} 在 Linux/Mac 中是 /,在 Windows 中是\ (来源)。不幸的是,VS Code 没有为 :; 定义变量,因此如果 .env 文件中有多个条目,则 PYTHONPATH= 不能在跨平台上使用。这就是为什么我使用 pylint 的 --init-hook 来预先添加 sys.path - wisbucky
@darda 你不应该禁用pylint的缺失导入错误。我知道这并不容易,但是它是可以修复的。你需要尝试添加__init__.py文件,并正确设置sys.path。可以使用PYTHONPATH--init-hook "import sys, os; sys.path.insert(0, os.path.join('src', 'foo'))"来实现。 - wisbucky
显示剩余11条评论

48
这个问题值得点赞,因为文档缺少一些重要的细节。
示例:
假设你的项目布局是这样的
myproject/
    .vscode/
        settings.json
    .env
    src/
        a_module.py
    tests/
        test_a.py

打开settings.json文件并插入以下行
// On linux use "terminal.integrated.env.linux": {
"terminal.integrated.env.windows": {
    "PYTHONPATH": "${workspaceFolder}/src;${workspaceFolder}/tests"
},
// The next line can be omitted, unless you've modified the global default
"python.envFile": "${workspaceFolder}/.env",

请注意,${workspaceFolder} 会被解析为 myproject,而不是 .vscode 文件夹。
在 .env 文件中输入以下内容。
PYTHONPATH=src;test
# Paths are relative to the workspace folder, so above is equivalent to
# WORKSPACE_FOLDER=C:/full/path/to/myproject
# PYTHONPATH=${WORKSPACE_FOLDER}/src;${WORKSPACE_FOLDER}/tests

请注意,在Windows上,路径中的斜杠向前倾斜,就像这样/。在Windows上,不同的路径用;分隔(在其他平台上用:)。
最后一步,重新启动VS Code。 这篇博客很有帮助。

1
我曾认为 vscode 的 .env 文件不会像 ${WORKSPACE_FOLDER} 那样进行变量扩展?"变量替换仅在 VS Code 设置文件中受支持,无法在 .env 环境文件中工作。" - wisbucky
1
仍然没有帮助,ModuleNotFoundError 仍然存在。 - Vitamin C
我有两个虚拟环境,一个用于“src”,另一个用于“test”,如何使其工作?此外,我对工作区文件夹感到困惑。在“settings.json”中,您正在使用“workspaceFolder”,但在“.env”中,您正在使用“WORKSPACE_FOLDER”。这将如何工作? - Veb
.env中定义的环境变量接受相对路径,因此在上面的示例中,PYTHONPATH=src;tests就足够了。不仅不需要定义WORKSPACE_FOLDER,而且这样做也会使.env文件无法转移(例如将其包含在git中可能会导致用户之间出现问题)。 - Jonathan H
你能使用 workspace.code-workspace 文件吗? - mike01010
显示剩余5条评论

20

在.env文件中设置PYTHONPATH对我很有效。请注意,这种效果只适用于vscode及其运行的工具,例如pylint。

我的情况:

我的项目不是pip installable包,而只是一个源文件夹。(由于历史原因...)

myproject/src

该项目在一个pip requires文件中定义了依赖项。

我的设置:

  1. 我创建一个虚拟环境,并从requires文件安装包。
  2. 我在myproject文件夹中打开vscode - 这将成为vscode "项目"的根目录。
  3. 我指定vscode使用虚拟环境作为Python解释器。这将使已安装pip的依赖关系的导入工作。(对于代码分析、智能感知等)
  4. 要让来自我的项目源的导入也适用于vscode中的代码分析器(pylint 特别),我添加了一个.env文件,其中添加了我的项目源文件夹到PYTHONPATH中:
PYTHONPATH=./src:${PYTHONPATH}

18
请注意:在Windows系统中,必须使用分号';'作为分隔符!在环境文件中定义PYTHONPATH不具备跨平台功能:https://code.visualstudio.com/docs/python/environments#_use-of-the-pythonpath-variable。我个人曾经费了很长时间才通过困难的方式弄清楚这一点…… - ARF

18

OP似乎在问.env文件的路径语法和vscode设置, 以便找到和读取一些自定义模块文件. 我遇到了类似的问题, 我想让代码能够在脚本中导入我的自定义模块. 我不想把我的自定义模块放在python环境的文件夹里. 我也想避免将一个或多个路径设置为Windows环境变量中的用户变量的PYTHONPATH - 但如果您想这样做,它会有效.
我正在Windows 10的vscode中工作.

1) 语法:

a) 我发现以下路径语法在env文件中有效:

PYTHONPATH = C:/0APPS/PYTHON/_MODULES

我的.py模块文件在此文件夹中.

b) # 在.env文件中用于注释.

2) VSCODE设置: 我发现以下设置有效:

a) 像sunew在#2中说的那样, 我的设置: 使用vscode中的资源管理器打开所选项目工作区文件夹. 对我来说,那是Q:\420 PYTHON

b) 给env文件起一个名字,如vscode.env,并将其放置在该工作区顶层的文件夹中.

c) 打开vscode设置并搜索.env,其中在扩展 > Python下,您将找到"Python:env文件". 编辑框,添加您的env文件名称,就在.env之前. 例如. ${workspaceFolder} / vscode.env

d) 现在对于我而言import custom_modulename是有效的 - 在python交互窗口和脚本中.


10

对于像 Pyright 这样的工具,您可以在工作区设置文件 settings.json 中编辑 python.analysis.extraPaths。

示例:

{
    ...
    "python.analysis.extraPaths": [
        "src/apps",
        "src/override_apps"
    ],
    ...
    // next lines can be different
    "python.linting.enabled": true, 
    "python.linting.pylintEnabled": true,
    "python.linting.mypyEnabled": false,
    "python.pythonPath": "environment/bin/python",
    ...
}

6

编辑vs code工作区文件夹中的settings.json

{
"python.pythonPath": "*python package path*",
"terminal.integrated.env.windows": {
    "PYTHONPATH": "${workspaceFolder}/*sub folder*;*python package path*"
},
"python.defaultInterpreterPath": "*path to python exe*",
"python.analysis.extraPaths": [
    "*python package path*",
    "*python package path*"
],
"python.autoComplete.extraPaths": [
    "*python package path*",
    "*python package path*"
]}

运行良好!


1
你能提供更多信息吗?那段代码是做什么的? - Tyler2P
这里有太多的冗余。 - mike01010

4

我是一名Linux用户,我在使用vscode的Python插件时遇到了一些问题,需要和其他设置进行交互,但是以下方法对我有效:

  • 关闭所有工作区。

  • 添加一个单独的文件夹作为新工作区的根目录。

  • 在该文件夹中放置包含PYTHONPATH=/path/to/a:/path/to/b的.env文件,注意要将其完整地放在单独的一行上,不要在值周围使用双引号。

  • 重启vscode。

  • 创建一个test.py脚本,在其中导入文件夹内的一个包或模块。

  • vscode应该允许您的import语句,并且应该自动完成文件夹内的代码。


2

在Windows 10上,使用Python扩展v2021.10.1365161279和VSCode 1.6.2运行。调试基于.env文件进行,我使用了默认文件.env:
PYTHONPATH=<full_path_to_the_workspace_folder>

运行基于.vscode/settings.json文件,具有以下设置:
"terminal.integrated.env.windows": {"PYTHONPATH": "<full_path_to_the_workspace_folder>"}
仅当我更改路径时,我发现需要禁用+重新加载+启用扩展。


1
这里有三种解决问题的方式:
1/ 编辑 PYTHONPATH :
- 执行 export PYTHONPATH=/Users/.../Projects/MyNewProject/src - 运行文件时执行 python3 myfile.py 2/ 编辑 VSCode 设置:
- 在 VSCode 的 settings.json 文件中添加 "terminal.integrated.env.osx": {"PYTHONPATH": "${workspaceFolder}/src"} 3/ 在 src/ 目录下添加一个 setup.py 文件:
- 创建文件 src/setup.py
from setuptools import find_packages, setup

setup(
    name="sample",
    description="Sample Python Project",
    packages=find_packages(),
)
  • 运行python -m pip install -e ./src/命令,将src/目录下所有模块安装为包。

1

由于原因未知,我的.venv/Lib/site-packages/.pth解决方案失败了,以及我随后的.vscode\settings.json.env在我的Windows 10上无法运行*,因此我采用了环境无关的方法来导入./src/lib.py./test/test_lib.py中:

import os, sys
sys.path.append(os.path.join(os.path.dirname(__file__), '../src'))
from lib import foo

这也适用于非IDE终端,当我在函数之间忘记添加额外的换行时,VS Code的pycodestyle仍会发出警告。

*:VS Code 1.70.0版本说明:

从.env文件中加载环境变量

已经对从.env文件中加载环境变量进行了一些修复,包括检测.env文件的更改。Python内核现在将从设置python.envFile中定义的文件中加载环境变量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接