相对导入- ModuleNotFoundError:没有名为x的模块

这是我第一次真正坐下来尝试python 3,而且似乎失败得很惨。我有以下两个文件:

  1. test.py
  2. config.py

py中定义了一些函数和一些变量。我将其归纳为以下几点:

config.py

debug = True

test.py

import config
print (config.debug)

我还有一个__init__.py

然而,我得到以下错误:

ModuleNotFoundError: No module named 'config'

我知道py3约定使用绝对导入:

from . import config

然而,这会导致以下错误:

ImportError: cannot import name 'config'

所以我不知道该怎么做……任何帮助都非常感激。:)

886082 次浏览

尝试你的例子

from . import config
< p > 得到如下SystemError: < br > /usr/bin/python3.4 test.py < br > 回溯(最近一次调用):
文件"test.py",第1行,
从。导入配置< br > SystemError: Parent module " not loaded, cannot perform relative import .


这对我来说很有用:

import config
print('debug=%s'%config.debug)


>>>debug=True

用Python测试:3.4.2 - PyCharm 2016.3.2


除此之外,PyCharm提供给你导入此名称 你必须点击config,然后出现一个帮助图标enter image description here < / p >

你不能从你执行的文件中进行相对导入,因为__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

这里test在“ryan”里面;包并可以执行相对导入。import config失败,因为Python 3中不允许隐式相对导入。

希望这对你有所帮助。

附注:如果你坚持使用Python 3,就不再需要__init__.py文件了。

这个例子适用于Python 3.6。

我建议去PyCharm中的Run -> Edit Configurations,删除那里的所有条目,并尝试再次通过PyCharm运行代码。

如果不工作,检查你的项目解释器(设置->项目解释器)和运行配置默认值(run ->编辑配置…)。

正如在原帖子的评论中所述,这似乎是我使用的python解释器的问题,而不是python脚本的问题。我从WinPython包切换到python.org的官方python 3.6,它工作得很好。谢谢大家的帮助:)

我想明白了。非常令人沮丧,尤其是来自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)

main.py

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

我不得不修改modi .py的import语句来修复它

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

设置PYTHONPATH也可以帮助解决这个问题。

下面是如何在Windows上做到这一点

set PYTHONPATH=.

在调用模块之前,声明正确的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')

您可以简单地将以下文件添加到测试目录,然后python将在测试之前运行它

__init__.py file


import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

你必须将项目的路径附加到PYTHONPATH,并确保使用绝对的进口


适用于UNIX (Linux, OSX,…)

export PYTHONPATH="${PYTHONPATH}:/path/to/your/project/"

对于Windows

set PYTHONPATH=%PYTHONPATH%;C:\path\to\your\project\

绝对的进口

假设我们有如下的项目结构,

└── 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

要获得更全面的解释,请参阅文章How to fix ModuleNotFoundError and ImportError

在项目根目录下设置PYTHONPATH环境变量。

考虑类unix:

export PYTHONPATH=.

试一试

from . import config

它所做的是从相同的文件夹级别导入。如果你直接导入,它会假设它是一个下属

如果你使用的是python3 +,那么尝试添加下面的行

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)

对我来说,简单地添加当前目录就可以了。

使用以下结构:

└── myproject
├── a.py
└── b.py

a.py:

from b import some_object
# returns ModuleNotFound error


from myproject.b import some_object
# works

我在一台Linux机器上工作。我有同样的问题,当我运行python my_module/__main__.py

如果在运行脚本之前运行命令export PYTHONPATH=.,则错误将被修复。

export PYTHONPATH=.
python my_module/__main__.py

你可以使用这些语句来设置工作目录,我用python3就可以

import os
import sys
sys.path.insert(1, os.getcwd())

根据我的经验,PYTHONPATH环境变量并不是每次都有效。

在我的例子中,我的pytest只在我添加绝对路径时工作: sys.path.insert ( 0,“/用户/ bob /项目/回购/ lambda" ) < / p >

我看到许多答案导入sysos。这是GitHub副驾驶给我的一个没有提到的更短的:

import sys


sys.path.append(__file__.rsplit("/", 1)[0])

将此添加到我的python脚本顶部也解决了这个问题。