Relative imports - ModuleNotFoundError: No module named x
Relative imports - ModuleNotFoundError: No module named x
这是我第一次真正坐下来尝试 python 3,但似乎失败得很惨。我有以下两个文件:
- test.py
- config.py
config.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'
所以我不知道在这里做什么...非常感谢任何帮助。 :)
试过你的例子
from . import config
got the following SystemError:
/usr/bin/python3.4 test.py
Traceback (most recent call last):
File "test.py", line 1, in
from . import config
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
,然后会出现 帮助图标。
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
这里的“测试”是 __main__
模块并且不知道任何关于属于包的信息。但是 import config
应该可以工作,因为 ryan
文件夹将添加到 sys.path
.
让我们 运行 main.py
代替:
$ python main.py
ryan.test
True
Absolute import failed
这里的测试在“ryan”包中,可以执行相关导入。 import config
失败,因为 Python 中不允许隐式相对导入 3.
希望对您有所帮助。
P.S.: 如果您坚持使用 Python 3,则不再需要 __init__.py
个文件。
此示例适用于 Python 3.6.
我建议转到 PyCharm 中的 Run -> Edit Configurations
,删除那里的所有条目,然后再次尝试 运行 通过 PyCharm 的代码。
如果这不起作用,请检查您的项目解释器(设置 -> 项目解释器)和 运行 配置默认值(运行 -> 编辑配置...)。
正如在对原始 post 的评论中所述,这似乎是我出于某种原因使用的 python 解释器的问题,而不是 [=13] 的问题=] 脚本。我从 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
我不得不修改 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
设置 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
在根项目目录中设置PYTHONPATH
环境变量。
考虑类 UNIX:
export PYTHONPATH=.
尝试
from . import config
这样做是从同一文件夹级别导入。如果您直接尝试导入它会假定它是从属
如果您使用的是 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)
对我来说,只需添加当前目录即可。
使用以下结构:
└── 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, "/Users/bob/project/repo/lambda"
)
这是我第一次真正坐下来尝试 python 3,但似乎失败得很惨。我有以下两个文件:
- test.py
- config.py
config.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'
所以我不知道在这里做什么...非常感谢任何帮助。 :)
试过你的例子
from . import config
got the following SystemError:
/usr/bin/python3.4 test.py
Traceback (most recent call last):
File "test.py", line 1, in
from . import config
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
,然后会出现 帮助图标。
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
这里的“测试”是 __main__
模块并且不知道任何关于属于包的信息。但是 import config
应该可以工作,因为 ryan
文件夹将添加到 sys.path
.
让我们 运行 main.py
代替:
$ python main.py
ryan.test
True
Absolute import failed
这里的测试在“ryan”包中,可以执行相关导入。 import config
失败,因为 Python 中不允许隐式相对导入 3.
希望对您有所帮助。
P.S.: 如果您坚持使用 Python 3,则不再需要 __init__.py
个文件。
此示例适用于 Python 3.6.
我建议转到 PyCharm 中的 Run -> Edit Configurations
,删除那里的所有条目,然后再次尝试 运行 通过 PyCharm 的代码。
如果这不起作用,请检查您的项目解释器(设置 -> 项目解释器)和 运行 配置默认值(运行 -> 编辑配置...)。
正如在对原始 post 的评论中所述,这似乎是我出于某种原因使用的 python 解释器的问题,而不是 [=13] 的问题=] 脚本。我从 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
我不得不修改 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
设置 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
在根项目目录中设置PYTHONPATH
环境变量。
考虑类 UNIX:
export PYTHONPATH=.
尝试
from . import config
这样做是从同一文件夹级别导入。如果您直接尝试导入它会假定它是从属
如果您使用的是 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)
对我来说,只需添加当前目录即可。
使用以下结构:
└── 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, "/Users/bob/project/repo/lambda" )