首页 > 解决方案 > 在 VSCode 中调试 python 模块的问题

问题描述

我的 python 练习项目有以下目录结构:

.
├── data
├── ds-and-algo
├── exercises
|   ├── __init__.py
│   ├── armstrong_number.py
│   ├── extract_digits.py
├── output

extract_digits.py看起来像这样:

def extract_digits(n):
    pass

armstrong_number.py我有以下内容:

from .extract_digits import extract_digits

如果我运行,则从根项目目录

python exercises/armstrong_number.py

我明白了ModuleNotFoundError: no module named exercises

运行以下带有-m标志的逗号可解决该错误:

python -m exercises.armstrong_number

但是VSCode为了调试文件,我有以下调试配置launch.json

{
"version": "0.2.0",
    "configurations": [
        {
            "name": "Python Module",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "pythonPath": "${config:python.pythonPath}",
            "module": "exercises.${fileBasenameNoExtension}",
            "cwd": "${workspaceRoot}",
            "env": {"PYTHONPATH":"${workspaceRoot}"}
        }
    ]
}

然而这有几个问题:

1)对于不同的文件夹,例如ds-and-algo,我必须手动编辑launch.json文件调试配置中的模块条目

"module" : "ds-and-algo.${fileBaseNameNoExtension}"

如果我有嵌套文件夹配置,例如:

exercises
├── tough
|   | __init__.py
|   ├──ex1.py
|   ├──ex2.py
├── easy

我再次必须手动将launch.json文件中的调试配置编辑为:(考虑子文件夹的情况tough

"module": "exercises.tough.${fileBaseNameNoExtension}"

我需要实现一个一般情况,根据正在调试的文件,文件中的"module"条目launch.json应该是:

"module": "folder1.folder2.folder3.....foldern.script"

就像fileBaseNameNoExtension,VSCode一些其他预定义的变量

其中一个变量是relativeFile,它是当前打开文件的相对路径,workspaceFolder 因此对于文件ex1.py,变量relativeFile将是exercises/tough/ex1.py

我需要操作此字符串并将其转换为,如果我可以在文件的条目中exercises.tough.ex1编写和执行 bash 命令,这很简单。但我无法做到这一点。但是,VSCode 中的链接预定义变量有一个关于Command variables的部分,其中指出:"module"launch.json

如果上面的预定义变量不够用,您可以通过${command:commandID}语法使用任何 VS Code 命令作为变量。

此链接包含许多其他可能有用的信息。我不是 python 专家,而且绝对不知道任何 javascript,如果这是解决这个问题所需要的。

标签: pythonvisual-studio-code

解决方案


我无法重现您的错误:ModuleNotFoundError: no module named exercises.

使用以下文件

exercises/extract_digits.py

def extract_digits(n):
  return 10

exercises/armstrong_number.py

from extract_digits import extract_digits

def armstrong_number(n):
  return extract_digits(n)

if __name__ == "__main__": 
  print armstrong_number(3)

如果您使用 Python3,请将 print 语句更改为:print(armstrong_number(3))并更改使用的 Python 解释器。

如果您的当前目录是项目根目录并且您运行

python exercises/armstrong_number.py

你在控制台中得到数字 10


在 Visual Studio Code 中,您使用了错误的启动配置。

你只是在运行 python 程序,所以你应该使用Python: Current File配置。 launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Python: Current File",
      "type": "python",
      "request": "launch",
      "program": "${file}",
      "console": "integratedTerminal",
    }
  ]
}
  1. 在任何目录中打开要运行/调试的示例 py 文件。
  2. 或使其成为当前文件
  3. 选择调试侧栏
  4. 选择Python: Current File配置
  5. 单击“绿色”三角形。

现在构建并运行了一个复杂的命令。它将 CWD 设置为当前文件的目录并在当前文件上启动调试器。


如果您确实需要启动模块,您可以在 VSC 中使用 a并为每个根目录Multi-Root Workspace单独配置launch.json


如果你想使用${command:commandID}语法,你可以构造一个简单的扩展名,它使用activeTextEditor并根据文件名构造一个字符串
编辑

另一种选择是使用多次启动配置。

我已经删除了默认值有效或未使用的属性。

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Exercise",
      "type": "python",
      "request": "launch",
      "console": "integratedTerminal",
      "module": "exercises.${fileBasenameNoExtension}",
    },
    {
      "name": "Exercise.Easy",
      "type": "python",
      "request": "launch",
      "console": "integratedTerminal",
      "module": "exercises.easy.${fileBasenameNoExtension}",
    },
    {
      "name": "DS",
      "type": "python",
      "request": "launch",
      "console": "integratedTerminal",
      "module": "ds.${fileBasenameNoExtension}",
    }
  ]
}


您可以使用扩展命令变量来获取这个带有点分隔符的相对目录。

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Python: Module CmdVar",
      "type": "python",
      "request": "launch",
      "console": "integratedTerminal",
      "module": "${command:extension.commandvariable.file.relativeDirDots}.${fileBasenameNoExtension}",
    }
  ]
}

推荐阅读