问题:相对导入-ModuleNotFoundError:没有名为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'
因此,我对此无所适从……任何帮助将不胜感激。:)
回答 0
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中不允许隐式相对导入。
希望这会有所帮助。
PS:如果您坚持使用Python 3,则__init__.py
文件中不再需要。
回答 1
我想到了。非常令人沮丧,尤其是来自python2。
.
无论模块是相对的还是绝对的,都必须向模块添加a 。
我创建目录设置如下。
/main.py
--/lib
--/__init__.py
--/mody.py
--/modx.py
修改器
def does_something():
return "I gave you this string."
么
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的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
回答 2
设置PYTHONPATH也可以解决此问题。
这是在Windows上可以完成的方法
set PYTHONPATH=.
回答 3
您必须将模块的路径附加到PYTHONPATH
。
对于UNIX(Linux,OSX等)
export PYTHONPATH="${PYTHONPATH}:/path/to/your/module/"
对于Windows
set PYTHONPATH=%PYTHONPATH%;C:\path\to\your\module\
回答 4
试过你的例子
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
回答 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.6上有效。
我建议进入Run -> Edit Configurations
PyCharm,删除那里的所有条目,然后尝试再次通过PyCharm运行代码。
如果这不起作用,请检查项目解释器(“设置”->“项目解释器”)并运行默认配置(“运行”->“编辑配置…”)。
回答 8
在调用模块之前,声明正确的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')
回答 9
如原始帖子的评论中所述,这似乎是我出于任何原因使用的python解释器的问题,而不是python脚本出了点问题。我从WinPython包切换到了python.org上的官方python 3.6,它工作得很好。感谢大家的帮助:)
回答 10
如果您使用的是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)
回答 11
尝试
from . import config
这是从同一文件夹级别导入的。如果您直接尝试导入,则假定它是下属