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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43728431/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 23:20:29  来源:igfitidea点击:

Relative imports - ModuleNotFoundError: No module named x

pythonpython-3.xpackagepython-importrelative-import

提问by blitzmann

This is the first time I've really sat down and tried python 3, and seem to be failing miserably. I have the following two files:

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

  1. test.py
  2. config.py
  1. 测试文件
  2. 配置文件

config.py has a few functions defined in it as well as a few variables. I've stripped it down to the following:

config.py 中定义了一些函数以及一些变量。我已将其精简为以下内容:

enter image description here

在此处输入图片说明

However, I'm getting the following error:

但是,我收到以下错误:

ModuleNotFoundError: No module named 'config'

I'm aware that the py3 convention is to use absolute imports:

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

from . import config

However, this leads to the following error:

但是,这会导致以下错误:

ImportError: cannot import name 'config'

So I'm at a loss as to what to do here... Any help is greatly appreciated. :)

所以我不知道在这里做什么......非常感谢任何帮助。:)

采纳答案by blitzmann

As was stated in the comments to the original post, this seemed to be an issue with the python interpreter I was using for whatever reason, and not something wrong with the python scripts. I switched over from the WinPython bundle to the official python 3.6 from python.org and it worked just fine. thanks for the help everyone :)

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

回答by Igonato

TL;DR:you can't do relative imports from the file you executesince __main__module is not a part of a package.

TL;DR:你不能从你执行的文件中进行相对导入,因为__main__模块不是包的一部分。

Absolute imports- import something available on sys.path

绝对进口- 进口一些可用的东西sys.path

Relative imports- import something relative to the current module, must be a part of a package

相对导入- 导入与当前模块相关的东西,必须是包的一部分

If you're running both variants in exactly the same way, one of them should work. Anyway, here is an example that should help you understand what's going on, let's add another main.pyfile with the overall directory structure like this:

如果您以完全相同的方式运行这两种变体,则其中一种应该可以工作。无论如何,这是一个可以帮助您理解发生了什么的示例,让我们添加另一个main.py具有整体目录结构的文件,如下所示:

.
./main.py
./ryan/__init__.py
./ryan/config.py
./ryan/test.py

And let's update test.py to see what's going on:

让我们更新 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

Let's run test.py first:

让我们先运行 test.py:

$ python ryan/test.py
__main__
Relative import failed
True

Here "test" isthe __main__module and doesn't know anything about belonging to a package. However import configshould work, since the ryanfolder will be added to sys.path.

这里的“测试”__main__模块,不知道属于什么包。但是import config应该可以工作,因为该ryan文件夹将被添加到 sys.path。

Let's run main.py instead:

让我们运行 main.py:

$ python main.py
ryan.test
True
Absolute import failed

And here test is inside of the "ryan" package and can perform relative imports. import configfails since implicit relative imports are not allowed in Python 3.

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

Hope this helped.

希望这有帮助。

P.S.: if you're sticking with Python 3 there is no more need in __init__.pyfiles.

PS:如果您坚持使用 Python 3,则不再需要__init__.py文件。

回答by Igonato

I figured it out. Very frustrating, especially coming from python2.

我想到了。非常令人沮丧,尤其是来自python2。

You have to add a .to the module, regardless of whether or not it is relative or absolute.

.无论是相对的还是绝对的,您都必须向模块添加 a 。

I created the directory setup as follows.

我创建的目录设置如下。

/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()

when I execute main, this is what happens

当我执行 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'

I ran 2to3, and the core output was this

我跑了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

I had to modify mody.py's import statement to fix it

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

try:
    from modx import does_something
except ImportError:
    from .modx import does_something


def loaded():
    string = does_something()
    print(string)

Then I ran main.py again and got the expected output

然后我再次运行 main.py 并得到了预期的输出

$ python main.py
I gave you this string.

Lastly, just to clean it up and make it portable between 2 and 3.

最后,只是为了清理它并使其在 2 和 3 之间可移植。

from __future__ import absolute_import
from .modx import does_something

回答by Santosh Pillai

Setting PYTHONPATH can also help with this problem.

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

Here is how it can be done on Windows

这是在 Windows 上完成的方法

set PYTHONPATH=.

set PYTHONPATH=.

回答by Giorgos Myrianthous

You have to append the module's path to PYTHONPATH.

您必须将模块的路径附加到PYTHONPATH.



For UNIX (Linux, OSX, ...)

对于 UNIX(Linux、OSX、...)

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


For Windows

对于 Windows

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

回答by stovfl

Tried your example

试过你的例子

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

得到以下 SystemError:
/usr/bin/python3.4 test.py
Traceback (last last call last):
File "test.py", line 1, in
from . 导入配置系统错误
:父模块''未加载,无法执行相对导入



This will work for me:

这对我有用:

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

>>>debug=True

Tested with Python:3.4.2 - PyCharm 2016.3.2

用 Python 测试:3.4.2 - PyCharm 2016.3.2



Beside this PyCharm offers you to Import this name.
You hav to click on configand a help iconappears. enter image description here

除了这个 PyCharm 还为您提供导入这个名称
您必须单击config并出现一个帮助图标在此处输入图片说明

回答by Vinod Rane

You can simply add following file to your tests directory, and then python will run it before the tests

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

__init__.py file

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

回答by HoangYell

Declare correct sys.pathlist before you call module:

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

回答by Carson Crane

This example works on Python 3.6.

此示例适用于 Python 3.6。

I suggest going to Run -> Edit Configurationsin PyCharm, deleting any entries there, and trying to run the code through PyCharm again.

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

If that doesn't work, check your project interpreter (Settings -> Project Interpreter) and run configuration defaults (Run -> Edit Configurations...).

如果这不起作用,请检查您的项目解释器(设置 -> 项目解释器)并运行配置默认值(运行 -> 编辑配置...)。

回答by manasouza

Set PYTHONPATHenvironment variable in root project directory.

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

Considering UNIX-like:

考虑类 UNIX:

export PYTHONPATH=.