简体   繁体   English

在VSCode中调试python模块的问题

[英]Problem with debugging python modules in VSCode

I have the following directory structure for my python practice project: 我的python练习项目具有以下目录结构:

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

The extract_digits.py looks something like this: extract_digits.py看起来像这样:

def extract_digits(n):
    pass

In the armstrong_number.py I have the following: armstrong_number.py我具有以下内容:

from .extract_digits import extract_digits

From root project directory if I run 从根项目目录(如果运行)

python exercises/armstrong_number.py

I get ModuleNotFoundError: no module named exercises 我收到ModuleNotFoundError: no module named exercises

Running the following commad with -m flag resolves the error: 使用-m标志运行以下命令可解决该错误:

python -m exercises.armstrong_number

However using VSCode in order to debug the file, I have the following debug config launch.json : 但是使用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}"}
        }
    ]
}

However this has a few problems: 但是,这有一些问题:

1) For a different folder, for eg ds-and-algo , I have to manually edit the module entry in the launch.json file debug configuration to 1)对于其他文件夹,例如ds-and-algo ,我必须手动编辑launch.json文件调试配置中的模块条目以

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

In case I have nested folder configuration like: 如果我有嵌套的文件夹配置,例如:

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

I again have to manually edit the debug config in launch.json file to: (considering the case for the sub-folder tough ) 我再有手动编辑的调试配置launch.json文件:(考虑子文件夹的情况下tough

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

I need to implement a general case where depending on the file being debugged, the "module" entry in the launch.json file should be: 我需要实现一个一般情况,其中取决于要调试的文件, launch.json文件中的"module"条目应为:

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

Just like fileBaseNameNoExtension , VSCode has some other predefined variables : 就像fileBaseNameNoExtension一样, VSCode还有一些其他预定义的变量

One of the variables is relativeFile , which is the path of the current opened file relative to workspaceFolder So for the file ex1.py , the variable relativeFile will be exercises/tough/ex1.py . 变量之一是relativeFile ,它是当前打开的文件相对于workspaceFolder的路径。因此,对于文件ex1.py ,变量relativeFile将为exercises/tough/ex1.py

I need to manipulate this string and convert this to exercises.tough.ex1 , which is trivial if I can write and execute bash command inside the "module" entry in launch.json file. 我需要处理此字符串并将其转换为exercises.tough.ex1 ,如果我可以在launch.json文件中的"module"条目内编写并执行bash命令,这将是微不足道的。 But I am unable to do that. 但是我做不到。 However, the link predefined variables in VSCode has a section on Command variables , which states: 但是, VSCode中的链接预定义变量在 Command variables一节中指出:

if the predefined variables from above are not sufficient, you can use any VS Code command as a variable through the ${command:commandID} syntax. 如果上面的预定义变量不够用,可以通过$ {command:commandID}语法将任何VS Code命令用作变量。

This link has a bunch of other information that may be helpful. 此链接还有很多其他信息可能会有所帮助。 I am no expert in python, and definitely don't know any javascript, if that is what is required to solve this problem. 我不是python的专家,并且绝对不知道任何javascript,如果那是解决此问题的必要条件。

I can't reproduce your error: ModuleNotFoundError: no module named exercises . 我无法重现您的错误: ModuleNotFoundError: no module named exercises

Using the following files 使用以下文件

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)

If you use Python3 change the print statement to: print(armstrong_number(3)) and change the used Python interpreter. 如果使用Python3,请将print语句更改为: print(armstrong_number(3))并更改使用的Python解释器。

If your current directory is the project root directory and you run 如果当前目录是项目根目录,并且您运行

python exercises/armstrong_number.py

You get the number 10 in the console 您在控制台中得到数字10


In Visual Studio Code you use the wrong Launch configuration. 在Visual Studio代码中,您使用了错误的启动配置。

You are just running python programs so you should use the Python: Current File configuration. 您只是在运行python程序,因此您应该使用Python: Current File配置。 launch.json

 { "version": "0.2.0", "configurations": [ { "name": "Python: Current File", "type": "python", "request": "launch", "program": "${file}", "console": "integratedTerminal", } ] } 
  1. Open the example py file you want to run/debug, in whatever directory it is. 在任何目录下打开要运行/调试的示例py文件。
  2. Or make it the current file 或将其设为当前文件
  3. Select the Debug Side Bar 选择调试侧栏
  4. Select the Python: Current File configuration 选择Python: Current File配置
  5. Click the "green" triangle. 单击“绿色”三角形。

Now a complicated command is constructed and run. 现在构造并运行了一个复杂的命令。 It will set the CWD to the directory of the current file and start the debugger on the current file. 它将CWD设置为当前文件的目录,并在当前文件上启动调试器。


If you really need the module launch you can use a Multi-Root Workspace in VSC and have a separate configured launch.json for each of the root directories 如果您确实需要启动模块,则可以在VSC中使用Multi-Root Workspace ,并为每个根目录分别配置一个launch.json


If you want to use the ${command:commandID} syntax you can construct a simple extension that uses the activeTextEditor and construct a string based on the file name 如果要使用${command:commandID}语法,则可以构造一个使用activeTextEditor的简单扩展,并根据文件名构造一个字符串。
Edit 编辑

Another option is to use Multiple Launch configurations. 另一个选择是使用多重启动配置。

I have removed the properties where the default value works or that are not used. 我删除了默认值有效或未使用的属性。

 { "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}", } ] } 


You can use the extension Command Variable to get this relative directory with dot separator. 您可以使用扩展命令变量来获取带点分隔符的相对目录。

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

I'm not sure about running bash scripts, although if it's possible to run JavaScript in the file, "ds-and-algo.(${fileBaseNameNoExtension}).split('/').join('.')" should do the trick. 我不确定要运行bash脚本,尽管如果可以在文件中运行JavaScript,则"ds-and-algo.(${fileBaseNameNoExtension}).split('/').join('.')"应该做到这一点。

Actually, the reason you need the -m flag at all is because you don't have __init__.py files in your folders. 实际上,根本不需要-m标志的原因是因为文件夹中没有__init__.py文件。 These files may be empty, but they're used by python to identify a module structure and thus allow nested and relative imports. 这些文件可能是空的,但是python使用它们来标识模块结构,从而允许嵌套和相对导入。 I hope adding those files should allow you to just run python exercises/armstrong_number.py or python ds-and-algo/tough/ex1.py 我希望添加这些文件应该允许您只运行python exercises/armstrong_number.pypython ds-and-algo/tough/ex1.py

There isn't a way to specify in your launch.json that you want it to calculate what the module you want to debug is. 无法在launch.json中指定要其计算要调试的模块的方法。 This is because it's technically impossible to get right 100% of the time due to namespace packages letting any directory represent a package. 这是因为,由于名称空间包让任何目录都代表一个包,从技术上讲不可能100%地正确。 Your best option is to create separate debug configurations per example you want to run in your launch.json (you can have as many as you want). 最好的选择是为每个要在launch.json运行的示例创建单独的调试配置(可以有launch.json多个)。 If doing that by hand is too tedious you could write a Python script to generate your launch.json for you. 如果手工操作太繁琐,则可以编写Python脚本来为您生成launch.json

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

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