简体   繁体   English

VSCode 1.39.x 和 Python 3.7.x:“ImportError:尝试在没有已知父包的情况下进行相对导入”- 在没有调试的情况下启动时 (CTRL+F5))

[英]VSCode 1.39.x & Python 3.7.x: "ImportError: attempted relative import with no known parent package" - when started without debugging (CTRL+F5))

  • when running Python test from withing VS Code using CTRL+F5 I'm getting error message使用 CTRL+F5 从 VS Code 运行 Python 测试时,我收到错误消息

    ImportError: attempted relative import with no known parent package ImportError:尝试在没有已知父项的情况下进行相对导入 package

错误消息文本:“ImportError:尝试在没有已知父包的情况下进行相对导入”

  • when running Python test from VS Code terminal by using command line使用命令行从 VS Code 终端运行 Python 测试时

    python test_HelloWorld.py python test_HelloWorld.py

    I'm getting error message我收到错误消息

    ValueError: attempted relative import beyong top-level package ValueError:尝试相对导入 beyong 顶级 package

错误消息:“ValueError:尝试相对导入超出顶级包”

Here is the project structure这是项目结构

项目结构

How to solve the subject issue(s) with minimal (code/project structure) change efforts?如何以最少的(代码/项目结构)变更努力解决主题问题?

TIA! TIA!

[Update] [更新]

I have got the following solution using sys.path correction:我使用 sys.path 更正得到了以下解决方案:

使用sys.path修正的主题问题解决方案

import sys
from pathlib import Path
sys.path[0] = str(Path(sys.path[0]).parent)

but I guess there still could be a more effective solution without source code corrections by using some (VS Code) settings or Python running context/environment settings (files)?但我想通过使用一些(VS 代码)设置或 Python 运行上下文/环境设置(文件),仍然可以有一个更有效的解决方案,无需更正源代码?

You're bumping into two issues.你遇到了两个问题。 One is you're running your test file from within the directory it's written, and so Python doesn't know what .. represents.一种是您正在编写的目录中运行测试文件,因此 Python 不知道..代表什么。 There are a couple of ways to fix this.有几种方法可以解决这个问题。

One is to take the solution that @lesiak proposed by changing the import to from solutions import helloWorldPackage but to execute your tests by running python tests/test_helloWorld.py .一种是通过将导入更改为from solutions import helloWorldPackage来采用@lesiak 提出的解决方案,但通过运行python tests/test_helloWorld.py来执行您的测试。 That will make sure that your project's top-level is in Python's search path and so it will see solutions .这将确保您的项目的顶层位于 Python 的搜索路径中,因此它将看到solutions

The other solution is to open your project in VS Code one directory higher (whatever directory that contains solutions and tests ).另一种解决方案是在 VS Code 一个更高的目录(包含solutionstests的任何目录)中打开您的项目。 You will still need to change how you execute your code, though, so you are doing it from the top-level as I suggested above.但是,您仍然需要更改执行代码的方式,因此您按照我上面的建议从顶层执行此操作。

Even better would be to either run your code using python -m tests.test_helloWorld , use the Python extension's Run command, or use the extension's Test Explorer.更好的是使用python -m tests.test_helloWorld运行您的代码,使用 Python 扩展的运行命令,或使用扩展的测试资源管理器。 All of those options should help you with how to run your code (you will still need to either change the import or open the higher directory in VS Code).所有这些选项都可以帮助您了解如何运行代码(您仍然需要更改导入或在 VS Code 中打开更高的目录)。

Do not use relative import.不要使用相对导入。 Simply change it to只需将其更改为

from solutions import helloWorldPackage as hw

Update更新

I initially tested this in PyCharm.我最初在 PyCharm 中对此进行了测试。 PyCharm has a nice feature - it adds content root and source roots to PYTHONPATH (both options are configurable). PyCharm 有一个不错的功能 - 它向 PYTHONPATH 添加内容根和源根(这两个选项都是可配置的)。

You can achieve the same effect in VS Code by adding a .env file:您可以通过添加.env文件在 VS Code 中实现相同的效果:

PYTHONPATH=.:${PYTHONPATH}

Now, the project directory will be in the PYTHONPATH for every tool that is launched via VS Code.现在,项目目录将位于通过 VS Code 启动的每个工具的 PYTHONPATH 中。 Now Ctrl+F5 works fine.现在 Ctrl+F5 工作正常。

Setup a main module and its source packages paths设置主模块及其源包路径

Solution found at:在以下位置找到解决方案:

Which also provide a neat in-depth video explanation其中还提供了简洁的深入视频解释


The solution to the attempted relative import with no known parent package issue, which is especially tricky in VScode (in opposite to Pycharm that provide GUI tools to flag folders as package), is to:attempted relative import with no known parent package的解决方案是:

Add configuration files for the VScode debugger为 VScode 调试器添加配置文件

Id Est add launch.json as a Module (this will always execute the file given in "module" key) and settings.json inside the MyProjectRoot/.vscode folder (manually add them if it's not there yet, or be guided by VScode GUI for Run & Debug ) Id Est 添加launch.json作为Module (这将始终执行“模块”键中给出的文件)和settings.json .json 在MyProjectRoot/.vscode文件夹中(如果还没有,请手动添加它们,或者由 VScode GUI 引导用于Run & Debug

launch.json setup launch.json设置

Id Est add an "env" key to launch.json containing an object with "PYTHONPATH" as key, and "${workspaceFolder}/mysourcepackage" as value Id Est 添加一个"env"键来launch.json ,其中包含一个 object,键为"PYTHONPATH" ,值为"${workspaceFolder}/mysourcepackage"
final launch.json configuration最终发布。json配置

settings.json setup settings.json设置

Id Est add a "python.analysis.extraPaths" key to settings.json containing a list of paths for the debugger to be aware of, which in our case is one ["${workspaceFolder}/mysourcepackage"] as value (note that we put the string in a list only for the case in which we want to include other paths too, it is not needed for our specific example but it's still a standard de facto as I know) Id Est 向settings.json添加一个"python.analysis.extraPaths"键,其中包含调试器要注意的路径列表,在我们的例子中是一个["${workspaceFolder}/mysourcepackage"]作为值(注意我们将字符串放在一个列表中,仅用于我们也想包含其他路径的情况,我们的具体示例不需要它,但据我所知,它仍然是事实上的标准)
final settings.json configuration最终设置。json配置

This should be everything needed to both work by calling the script with python from the terminal and from the VScode debugger.这应该是通过从终端和 VScode 调试器调用带有 python 的脚本来工作所需的一切。

An Answer From 2022 2022年的答案

Here's a potential approach from 2022. The issue is identified correctly and if you're using an IDE like VS Code, it doesn't automatically extend the python path and discover modules.这是从 2022 年开始的一种潜在方法。该问题已正确识别,如果您使用的是 VS Code 之类的 IDE,它不会自动扩展 python 路径并发现模块。

One way you can do this using an.env file that will automatically extend the python path.一种方法是使用 .env 文件来自动扩展 python 路径。 I used this website k0nze.dev repeatedly to find an answer and actually discovered another solution.我反复使用这个网站k0nze.dev来寻找答案,实际上发现了另一个解决方案。

Here are the drawbacks of the solution provided in the k0nze.dev solution:以下是 k0nze.dev 解决方案中提供的解决方案的缺点:

  • It only extends the python path via the launch.json file which doesn't effect running python outside of the debugger in this case它仅通过 launch.json 文件扩展 python 路径,这不会影响在这种情况下在调试器之外运行 python
  • You can only use the ${workspaceFolder} and other variables within an "env" variable in the launch.json, which gets overwritten in precedence by the existence of a.env file.您只能在 launch.json 中的“env”变量中使用 ${workspaceFolder} 和其他变量,该变量会优先被 a.env 文件的存在覆盖。
  • The solution works only within VS Code since it has to be written within the launch.json (- overall portability)该解决方案仅适用于 VS Code,因为它必须在启动时编写。json(- 整体可移植性)

The.env File .env 文件

In your example tests falls under it's own directory and has it's own init .py.在您的示例中,测试属于它自己的目录,并且有它自己的init .py。 In an IDE like VS Code, it's not going to automatically discover this directory and module.在像 VS Code 这样的 IDE 中,它不会自动发现这个目录和模块。 You can see this by creating the below script anywhere in your project and running it:您可以通过在项目中的任何位置创建以下脚本并运行它来看到这一点:

_path.py _path.py

from sys import path as pythonpath

print("\n ,".join(pythonpath))

You shouldn't see your ${workspaceFolder}/tests/ or if you do, it's because your _path.py script is sitting in that directory and python automatically adds the script path to pythonpath.你不应该看到你的 ${workspaceFolder}/tests/ 或者如果你看到了,那是因为你的 _path.py 脚本位于该目录中,并且 python 自动将脚本路径添加到 pythonpath。 To solve this issue across your project, you need to extend the python path using.env file across all files in your project.要在整个项目中解决此问题,您需要在项目中的所有文件中使用 .env 文件扩展 python 路径。

To do this, use dot notation to indicate your ${workspaceFolder} in lieu of being able to actually use ${workspaceFolder}.为此,请使用点符号来指示您的 ${workspaceFolder},而不是能够实际使用 ${workspaceFolder}。 You have to do dot notation because.env files do not do variable assignment like ${workspaceFolder}.您必须使用点表示法,因为 .env 文件不会像 ${workspaceFolder} 那样进行变量赋值。 Your env file should look like:您的 env 文件应如下所示:

Windows Windows

PYTHONPATH = ".\\tests\\;.\\" 

Mac / Linux / etc Mac/Linux/等

PYTHONPATH = "./tests/:./"

where:在哪里:

  • ; ; and: are the path separators for environment variables for windows and Mac respectively和:分别是 windows 和 Mac 环境变量的路径分隔符
  • ./tests/ and.\tests\ extend python path to the files within the module tests for import in the init .py ./tests/ 和.\tests\ 扩展 python 模块测试中文件的路径,以便在init .py 中导入
  • ./ and.\ extend the python path to modules tests and presumably solutions? ./ and.\ 将 python 路径扩展到模块测试和可能的解决方案? I don't know if solutions is a module but I'm going to run with it.我不知道解决方案是否是一个模块,但我将使用它。

Test It Out测试一下

Now re-run your _path.py script and you should see permanent additions to your path.现在重新运行您的_path.py脚本,您应该会看到路径的永久添加。 This works for deeply nested modules as well if your company has a more stringent project structure.如果您的公司有更严格的项目结构,这也适用于深度嵌套的模块。

VS Code VS 代码

If you are using VS Code, you cannot use environment variables provided by VS Code in the.env file.如果您使用的是 VS Code,则不能在 .env 文件中使用 VS Code 提供的环境变量。 This includes ${workspaceFolder}, which is very handy to extend a file path to your currently open folder.这包括 ${workspaceFolder},它可以非常方便地将文件路径扩展到您当前打开的文件夹。 I've beaten myself up trying to figure out why it's not adding these environment variables to the path for a very long time now and it seems我已经打败了自己,试图弄清楚为什么长一段时间没有将这些环境变量添加到路径中,而且似乎

The solution is instead to use dot notation to prepend the path by using relative file path.解决方案是使用点符号通过使用相对文件路径来预先添加路径。 This allows the user to append a file path relative to the project structure and not their own file structure.这允许用户给 append 一个文件路径相对于项目结构而不是他们自己的文件结构。

For Other IDE's对于其他 IDE

The reason the above is written for VS Code is because it automatically reads in the.env file every time you run a python file.上面是为 VS Code 编写的原因是因为它会在您每次运行 python 文件时自动读取 .env 文件。 This functionality is very handy and unless your IDE does this, you will need the help of the dotenv package.此功能非常方便,除非您的 IDE 这样做,否则您将需要dotenv package 的帮助。

You can actually see the location that your version of VS Code is looking for by searching for the below setting in your preferences:您实际上可以通过在您的首选项中搜索以下设置来查看您的 VS Code 版本正在寻找的位置:

VSCode settings env file VSCode 设置环境文件

Anyways, to install the package you need to import.env files with, run:无论如何,要安装 package,您需要 import.env 文件,运行:

pip install python-dotenv

In your python script, you need to run and import the below to get it to load the.env file as your environment variables:在您的 python 脚本中,您需要运行并导入以下内容以使其加载 .env 文件作为您的环境变量:

from dotenv import load_dotenv()

# load env variables 
load_dotenv()

"""
The rest of your code here
"""

That's It而已

Congrats on making it to the bottom.恭喜你跌到谷底。 This topic nearly drove me insane when I went to tackle it but I think it's helpful to be elaborate and to understand the issue and how to tackle it without doing hacky sys.path appends or absolute file paths.当我去解决这个话题时,这个话题几乎让我发疯,但我认为详细说明和理解这个问题以及如何在不使用 sys.path 附加或绝对文件路径的情况下解决它是有帮助的。 This also gives you a way to test what's on your path and an explanation of why each path is added in your project structure.这也为您提供了一种测试路径上的内容的方法,并解释了为什么将每个路径添加到项目结构中。

I was just going through this with VS Code and Python (using Win10) and found a solution.我只是通过 VS Code 和 Python(使用 Win10)来解决这个问题并找到了解决方案。 Below is my project folder.下面是我的项目文件夹。 Files in folder "core" import functions from folder "event", and files in folder "unit tests" import functions from folder "core". “core”文件夹中的文件从“event”文件夹中导入函数,“unit tests”文件夹中的文件从“core”文件夹中导入函数。

I could run and debug the top-level file file_gui_tk.py within VS Code but I couldn't run/debug any of the files in the sub-folders due to import errors.我可以在 VS Code 中运行和调试顶级文件 file_gui_tk.py,但由于导入错误,我无法运行/调试子文件夹中的任何文件。 I believe the issue is that when I try to run/debug those files, the working directory is no longer the project directory and consequently the import path declarations no longer work.我认为问题在于,当我尝试运行/调试这些文件时,工作目录不再是项目目录,因此导入路径声明不再有效。

Folder Structure:文件夹结构:

testexample
    core
        __init__.py
        core_os.py
        dir_parser.py
    events
        __inits__.py
        event.py
    unit tests
        list_files.py
        test_parser.py
.env
file_gui_tk.py

My file import statements:我的文件导入语句:

in core/core_os.py:在核心/core_os.py 中:

 from events.event import post_event

in core/dir_parser.py:在核心/dir_parser.py 中:

from core.core_os import compare_file_bytes, check_dir
from events.event import post_event

To run/debug any file within the project directory, I added a top level.env file with contents:为了运行/调试项目目录中的任何文件,我添加了一个顶级 level.env 文件,内容如下:

PYTHONPATH="./"  

Added this statement to the launch.json file:将此语句添加到 launch.json 文件中:

"env": {"PYTHONPATH": "/testexample"},

And added this to the settings.json file并将其添加到 settings.json 文件中

"terminal.integrated.env.windows": {"PYTHONPATH": "./",}

Now I can run and debug any file and VS Code finds the import dependencies within the project.现在我可以运行和调试任何文件,VS Code 会在项目中找到导入依赖项。

I haven't tried this with a project dir structure more than two levels deep.我还没有尝试过超过两层深度的项目目录结构。

暂无
暂无

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

相关问题 ImportError:尝试相对导入,没有已知的父包 - ImportError: attempted relative import with no known parent package 导入错误 - 在没有已知父包的情况下尝试相对导入 - ImportError - attempted relative import with no known parent package Python/Flask ImportError:尝试在没有已知父包的情况下进行相对导入 - Python/Flask ImportError: attempted relative import with no known parent package ImportError:尝试在没有已知父包的情况下进行相对导入 - Python - ImportError: attempted relative import with no known parent package - Python 导入错误:尝试在没有已知父包的情况下进行相对导入? - ImportError: attempted relative import with no known parent package? ImportError:尝试在没有已知父 package 的情况下进行相对导入:( - ImportError: attempted relative import with no known parent package :( Python ImportError:尝试在没有已知父包的情况下进行相对导入 - Python ImportError: attempted relative import with no known parent package Python:“ImportError:在没有已知父包的情况下尝试相对导入” - Python: “ImportError: attempted relative import with no known parent package” Python3 ImportError:尝试在没有已知父项的情况下进行相对导入 package - Python3 ImportError: attempted relative import with no known parent package 尝试使用 vscode 在 anaconda(python 3.8.5)中没有已知父 package 的相对导入 - attempted relative import with no known parent package in anaconda(python 3.8.5) with vscode
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM