相对导入 - ModuleNotFoundError:没有名为 x 的模块
- 2025-01-09 08:46:00
- admin 原创
- 18
问题描述:
这是我第一次真正坐下来尝试 Python 3,但似乎失败了。我有以下两个文件:
测试.py
配置.py
config.py 中定义了一些函数以及一些变量。我将其精简为以下内容:
配置.py
debug = True
测试.py
import config
print (config.debug)
我也有一个__init__.py
但是,我收到以下错误:
ModuleNotFoundError: No module named 'config'
我知道 py3 约定是使用绝对导入:
from . import config
但是,这会导致以下错误:
ImportError: cannot import name 'config'
所以我不知道该做什么......非常感谢任何帮助。:)
解决方案 1:
TL;DR:由于模块不是包的一部分,因此您无法从执行的文件进行相对导入。__main__
绝对导入- 导入可用的东西sys.path
相对导入- 导入相对于当前模块的内容,必须是包的一部分
如果您以完全相同的方式运行这两个变体,则其中一个应该可以工作。以下示例应该可以帮助您了解发生了什么。让我们添加另一个main.py
文件,其整体目录结构如下:
.
./main.py
./ryan/__init__.py
./ryan/config.py
./ryan/test.py
让我们更新一下test.py
,看看发生了什么:
# config.py
debug = True
# test.py
print(__name__)
try:
# Trying to find module in the parent package
from . import config
print(config.debug)
del config
except ImportError:
print('Relative import failed')
try:
# Trying to find module on sys.path
import config
print(config.debug)
except ModuleNotFoundError:
print('Absolute import failed')
# main.py
import ryan.test
我们test.py
先来运行一下:
$ python ryan/test.py
__main__
Relative import failed
True
此处的“test”是模块__main__
,不知道它属于哪个包。但是import config
应该可以工作,因为ryan
文件夹将被添加到sys.path
。
让我们运行main.py
一下:
$ python main.py
ryan.test
True
Absolute import failed
此处测试位于“ryan”包内并可以执行相对导入。import config
由于 Python 3 不允许隐式相对导入,因此失败。
希望这有帮助。
PS:如果您坚持使用 Python 3,则不再需要__init__.py
文件。
解决方案 2:
您必须附加项目路径PYTHONPATH
并确保使用绝对导入。
对于 UNIX(Linux、OSX 等)
export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"
对于 Windows
set PYTHONPATH=%PYTHONPATH%;C:path oyourproject\n
绝对进口
假设我们有以下项目结构,
└── myproject
├── mypackage
│ ├── __init__.py
│ ├── a.py
└── anotherpackage
├── __init__.py
├── b.py
├── c.py
└── mysubpackage
├── __init__.py
└── d.py
只需确保从项目的根目录开始引用每个导入即可。例如,
# in module a.py
import anotherpackage.mysubpackage.d
# in module b
import anotherpackage.c
import mypackage.a
有关更全面的解释,请参阅文章如何修复 ModuleNotFoundError 和 ImportError
解决方案 3:
我找到了答案。非常令人沮丧,尤其是来自 python2。
您必须.
向模块添加,无论它是相对的还是绝对的。
我创建了如下的目录设置。
/main.py
--/lib
--/__init__.py
--/mody.py
--/modx.py
modx.py
def does_something():
return "I gave you this string."
mody.py
from modx import does_something
def loaded():
string = does_something()
print(string)
主程序
from lib import mody
mody.loaded()
当我执行 main 时,会发生以下情况
$ python main.py
Traceback (most recent call last):
File "main.py", line 2, in <module>
from lib import mody
File "/mnt/c/Users/Austin/Dropbox/Source/Python/virtualenviron/mock/package/lib/mody.py", line 1, in <module>
from modx import does_something
ImportError: No module named 'modx'
我运行了 2to3,核心输出如下
RefactoringTool: Refactored lib/mody.py
--- lib/mody.py (original)
+++ lib/mody.py (refactored)
@@ -1,4 +1,4 @@
-from modx import does_something
+from .modx import does_something
def loaded():
string = does_something()
RefactoringTool: Files that need to be modified:
RefactoringTool: lib/modx.py
RefactoringTool: lib/mody.py
我必须修改 mody.py 的导入语句来修复它
try:
from modx import does_something
except ImportError:
from .modx import does_something
def loaded():
string = does_something()
print(string)
然后我再次运行 main.py 并得到预期的输出
$ python main.py
I gave you this string.
最后,只需清理它并使其可在 2 和 3 之间移植。
from __future__ import absolute_import
from .modx import does_something
解决方案 4:
设置 PYTHONPATH 也可以帮助解决这个问题。
以下是在 Windows 上如何完成此操作
set PYTHONPATH=.
解决方案 5:
您只需将以下文件添加到您的测试目录中,然后 Python 将在测试之前运行它
__init__.py file
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
解决方案 6:
PYTHONPATH
在根项目目录中设置环境变量。
考虑类似 UNIX 的:
export PYTHONPATH=.
解决方案 7:
如果你使用的是 Python 3+,请尝试添加以下几行
import os, sys
dir_path = os.path.dirname(os.path.realpath(__file__))
parent_dir_path = os.path.abspath(os.path.join(dir_path, os.pardir))
sys.path.insert(0, parent_dir_path)
解决方案 8:
尝试了你的例子
from . import config
得到以下 SystemError:
/usr/bin/python3.4 test.py
Traceback(最近一次调用最后一次):
文件“test.py”,第 1 行,来自
。导入配置
SystemError: 父模块''未加载,无法执行相对导入
这对我有用:
import config
print('debug=%s'%config.debug)
>>>debug=True
使用 Python:3.4.2 - PyCharm 2016.3.2 进行测试
除此之外,PyCharm 还为您提供导入此名称的功能。
您必须单击config
,然后会出现一个帮助图标。
解决方案 9:
在调用模块之前声明正确的sys.path列表:
import os, sys
#'/home/user/example/parent/child'
current_path = os.path.abspath('.')
#'/home/user/example/parent'
parent_path = os.path.dirname(current_path)
sys.path.append(parent_path)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'child.settings')
解决方案 10:
我在 Linux 机器上工作。运行时遇到了同样的问题python my_module/__main__.py
。
export PYTHONPATH=.
如果您在运行脚本之前运行该命令,则错误已被修复。
export PYTHONPATH=.
python my_module/__main__.py
解决方案 11:
尝试
from . import config
这样做的目的是从同一层级的文件夹导入。如果你直接尝试导入,它会假定它是下级
解决方案 12:
您可以使用这些语句来设置工作目录,这对我有用python3
import os
import sys
sys.path.insert(1, os.getcwd())
解决方案 13:
此示例适用于 Python 3.6。
我建议进入Run -> Edit Configurations
PyCharm,删除那里的所有条目,然后尝试再次通过 PyCharm 运行代码。
如果这不起作用,请检查您的项目解释器(设置->项目解释器)并运行配置默认值(运行->编辑配置...)。
解决方案 14:
正如原帖评论中所述,这似乎是我使用的 Python 解释器的问题,无论出于什么原因,而不是 Python 脚本的问题。我从 WinPython 软件包切换到 python.org 的官方 Python 3.6,它运行得很好。感谢大家的帮助 :)
解决方案 15:
对我来说,只需添加当前目录就行了。
使用以下结构:
└── myproject
├── a.py
└── b.py
a.py:
from b import some_object
# returns ModuleNotFound error
from myproject.b import some_object
# works
解决方案 16:
我看到很多答案都导入了sys
和os
。这是 GitHub Copilot 给我的一个尚未提及的较短版本:
import sys
sys.path.append(__file__.rsplit("/", 1)[0])
将其添加到我的 Python 脚本的顶部也解决了该问题。
解决方案 17:
根据我的经验,PYTHONPATH 环境变量并不总是起作用。
就我而言,我的 pytest 仅在添加绝对路径时才有效: sys.path.insert( 0, "/Users/bob/project/repo/lambda" )
解决方案 18:
要让 Bash 自动识别您所在的项目目录:
sudo nano ~/.bashrc
或者
sudo nano ~/.bash_profile
在 bash 文件的底部:
function set_pythonpath {
export PYTHONPATH="$(pwd):$PYTHONPATH"
}
PROMPT_COMMAND=set_pythonpath
保存并退出:
Ctrl + X
Y
通过以下方式测试您的更改:
cat ~/.bashrc
解决方案 19:
现有的答案很好地解释了问题的可能原因。对于那些因尝试相对导入而导致异常的情况,我发现以下方法可以帮助解决:
搜索项目文件
from .
将所有导入更新为绝对导入
对所有新导入使用绝对导入
这很麻烦,而且灵活性较差,但有助于避免循环导入引起的错误。
根据我的经验,导致这些问题的另一个常见(尽管不太常见)原因是命名空间冲突。此错误往往是最难调试的错误,因为错误消息中很少显示冲突。
在几乎所有情况下,都需要手动进行特定上下文的调试。但是,一般示例如下:
.
└── root/
├── apps/
│ ├── ...
| |── app2/
│ └── app2/
│ ├── ...
│ └── main.py
└── venv/
├── ...
└── Lib/
└── site-packages/
├── ...
└── django/
├── ...
└── apps
在root/apps/app1/main.py
文件中,假设你从 导入了某些内容apps.app2
,并且还尝试从 导入了某些内容django.apps
。在大多数情况下,这会导致问题,因为apps
从两个位置进入命名空间。
但是,错误消息通常会让人相信这是一个循环导入a
,b
而b
实际上它是对导入内容的a
混淆b
。
解决方案 20:
这对我有用:它将 PYTHONPATH 环境变量设置为 PYTHANPATH 的当前值加上 PWD (当前工作目录)
$env:PYTHONPATH = "$env:PYTHONPATH;$PWD"
只需在用来执行 Python 脚本的终端中执行它即可。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理必备:盘点2024年13款好用的项目管理软件