VSCode模块未找到错误:没有名为X的模块。

27

我试图构建一个新的包,但是当我尝试从VSCode内部或终端运行任何文件时,我遇到了这个错误:

ModuleNotFoundError: No module name 'x'

我的当前文件夹结构如下:

package
|---module
|------__init__.py
|------calculations.py
|------miscfuncs.py
|---tests
|------__init__.py
|------test_calcs.py
|---setup.py
|---requirements.txt

然而,当我通过VSCode运行我的测试(PyTest)并在test_calcs.py中使用import module.calculations as calcfrom module.calculations import Class时,测试按预期工作-这让我感到困惑。

我知道这是一个常见的问题,但我无法想出一个适用于此处的解决方案。

我已经尝试检查系统路径中是否有工作目录,使用下面的代码。返回的目录列表中第一项是我正在工作的目录。

import sys
print(sys.path)

我在文件中也尝试使用以下内容,但并没有任何效果:

import module.calculations 
import .module.calculations
from . import miscfuncs

尝试使用 import .module.calculations 时,我会得到以下结果:

ModuleNotFoundError: No module named '__main__.module'; '__main__' is not a package

尝试在calculations.py中使用from . import miscfuncs时,我遇到了以下错误:

ImportError: cannot import name 'miscfuncs'

当我在模块文件夹中处理文件时,我可以使用相对导入:import calculations,它可以正常工作。这适用于模块内的文件,但不适用于我在test_calcs.py中工作时。

在我的setup.py中,我有一行:

packages=['module']

如果需要,我很高兴提供更多信息或者我的仓库链接以获取完整的代码。

编辑

按照remram的解决方案:

我已经更新了launch.json文件,包括CWDPYTHONPATH变量。

模块名称仍然没有被识别,但是,在VSCode中,导入文件中的函数可以很好地被IntelliSense捕捉到。

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

8
我卡了很长时间。对我找到答案有帮助的关键是研究VSCode和PyCharm在源或根目录概念处理上的差异。在PyCharm中,这一点非常容易,但在VSCode中需要付出更多的努力。我更改了launch.json和settings.json文件,将PYTHONPATH定义为"terminal.integrated.env.linux":{"PYTHONPATH":"${workspaceFolder}/src"}。 - Lepidopterist
3
非常感谢 @Lepidopterist!!我花了2个小时,直到看到你的评论才解决了问题。我的同事在PyCharm上运行它很顺利,但当我尝试运行时,出现了“模块未找到”的错误。我意识到唯一的区别就是IDE,但是找不到让它正常工作的方法。我所需要做的就是像你写的那样,在我的VSCode设置JSON文件中添加这行代码: "terminal.integrated.env.windows": { "PYTHONPATH": "${workspaceFolder}/.", }。 - AlonBA
7个回答

17

@lepidopterist的评论证明了数小时挣扎的关键所在...

解决方法:

  1. 按下Ctrl+Shift+P打开命令面板
  2. 进入Users.setting.json文件
  3. 添加以下行

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

参考:Settings.json

说明:

这是我的项目结构.... Project

我的项目中有三个模块/包!

  • module_a + module_b: 执行独立任务
  • convenience: 为所有其他模块提供实用函数

我想要做的事情!

  • 将所有实用函数保留在convenience模块中,并将它们导入到需要它们的任何模块中

不起作用的方法!

  • 相对导入失败

from ..convenience.utilities import add

结果是...

beyond top level package error
  • 绝对导入也失败了

from convenience.utilities import add

会出现以下情况...

ModuleNotFoundError: No module named 'convenience'
  • 将工作空间目录添加到PYTHONPATH也失败了

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

导致...

ModuleNotFoundError: No module named 'convenience'

为什么我提到的解决方案有效呢?

  • 因为我是在集成终端内运行module_a/task.py模块,这也就意味着需要将Pythonpath添加到终端中,以便将工作区目录地址添加到路径列表中。

(需要注意的一点是): 我的操作系统是Windows,所以它是......

"terminal.integrated.env.windows"

对于Linux系统,应该使用...

"terminal.integrated.env.linux"

修改 Users.Setting.json 后的结果:

输出


你真的救了我的命。我已经被这个问题困扰了很多天。 - Oscar
我已经卡在这个问题上有一段时间了。非常感谢你的解释。 - Binny

7

如果希望import module.calculations正常工作,请确保你在package文件夹下运行,而不是在package/module下运行。你还可以设置PYTHONPATH环境变量为package文件夹的路径。


1
我该如何在VSCode中从包文件夹运行代码?我猜绿色的运行按钮是在当前位置执行文件?另外,如果我设置PYTHONPATH,那么其他使用pip安装库的用户会受到什么影响? - rockdoctor
看看这个问题:https://dev59.com/LlkT5IYBdhLWcg3wbO4f。设置`PYTHONPATH`不会影响其他用户,只要你将其设置为标准值(例如顶级目录,其中包含您的`setup.py`)。 - remram
1
我按照CermakM的回复设置了CWD和PYTHONPATH,通过在launch.json中添加"cwd": "${workspaceFolder}""env": {"PYTHONPATH": "${cwd}"}。但是,在测试文件和模块目录中使用绝对导入时仍然出现错误。我可能忽略了一些简单的东西。 - rockdoctor
1
我发现在某些情况下,我仍然可以在子文件夹中运行。但在另一个项目中,出现了这个错误。 - Chang
@remram 这里的解决方案是什么?我很难理解这是如何解决问题的,特别是阅读了这些评论后,似乎问题仍未解决。 - SPYBUG96
很抱歉你遇到了麻烦,我不知道该说什么,只能重复上面的信息。你尝试过什么?发生了什么?考虑开另一个问题,这不是一个很好的故障排除地点。 - remram

5
为了调试 main.py,VSCode 需要知道明确的库路径。这可以通过在 launch.json 中设置环境变量 ('env') 来完成。第一步是在 .vscode 文件夹中创建 'launch.json'。
/
├── .vscode/
│   └── launch.json
├── mySubdir/
│   └── myLib.py
└── main.py

如果 main.py 想将 myLib.py 作为模块导入,只有当 mySubDir 是 Python 路径的一部分时,VSCode 才能实现这一点。

示例 launch.json:

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

{workspaceFolder} 是一个预定义的变量,将由 VSCode 进行替换。我还使用了 {pathSeparator},但发现在 Linux 中不起作用,所以现在我使用“:”代替。

这个帖子提供了更详细的解释:如何正确设置 Visual Studio Code 的 PYTHONPATH


1
根据您的描述,我没有得到足够的信息,但我认为我可以推测出您没有意识到的两个关键点。
  • 相对导入仅在包(或模块)内使用。

    参考Python官方文档 Modules

    请注意,相对导入是基于当前模块的名称。由于主模块的名称始终为__main__,因此用作Python应用程序的主模块的模块必须始终使用绝对导入。

    即使calculations.py位于包内,但您将其作为“主模块”运行,也不起作用。

  • 绝对导入的模块(您自己的)应位于您的当前工作目录下(位于sys.path或env PYTHONPATH中的路径)

    对于在测试中正常工作的问题,我认为它取决于您的“主模块”所在的目录,您应该仔细检查。

你只需要解决这两个问题,就能解决你的问题。

0

对我有用的是使用 pyproject.toml 文件:

[tool.pytest.ini_options]
pythonpath = [
  "."
]

0

不是

"program": "${file}"

尝试
"module": "folder.pythonfilename"

在末尾不要加上“.py”。

0
@lepidopterist的评论对我有用。
首先,我必须在我的settings.json文件中添加这一行。
"terminal.integrated.env.windows": { "PYTHONPATH": "${workspaceFolder}" }

只是通过添加这一行,对我来说并没有起作用。
所以在settings.json中添加了那行之后,我执行了window reload,结果很好。

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