无法找到模块:没有名为“__main__.xxxx”的模块;“__main__”不是一个包

2024-06-23 02:57:51 发布

您现在位置:Python中文网/ 问答频道 /正文

当前试图在Python3中工作,并使用绝对导入将一个模块导入到另一个模块,但我得到了错误ModuleNotFoundError: No module named '__main__.moduleB'; '__main__' is not a package。考虑这个项目结构:

proj
    __init__.py3 (empty)
    moduleA.py3
    moduleB.py3

模块A.py3

from .moduleB import ModuleB
ModuleB.hello()

模块B.py3

class ModuleB:
    def hello():
        print("hello world")

然后运行python3 moduleA.py3会产生错误。这里需要改变什么?


Tags: 模块nohelloismain错误py3not
3条回答

.moduleB是相对导入。只有先导入或加载父模块时,“相对”才起作用。这意味着您需要在当前运行时环境中的某处导入proj。当您使用命令python3 moduleA.py3时,它没有机会导入父模块。你可以:

  • from proj.moduleB import moduleB
  • 您可以创建另一个脚本,例如run.py,来调用from proj import moduleA

祝你在Python王国的旅途好运。

前言

我正在开发一个项目,它实际上是一个Python包,可以通过pip安装,但是它还公开了一个命令行界面。在用pip install .安装项目后,我的项目运行没有问题,但是嘿,谁每次在更改某个项目文件中的某些内容后都这样做?我需要通过简单的python mypackage/main.py来运行整个过程。

/my-project
    - README.md
    - setup.py
    /mypackage
      - __init__.py
      - main.py
      - common.py

同一问题的不同面

我试图从我的common.py模块导入main.py中的一些函数。我尝试了不同的配置,给出了不同的错误,我想和你们分享我的观察结果,并给未来的我留下一个简短的笔记。

相对进口

我首先尝试的是相对进口:

from .common import my_func

我用简单的python mypackage/main.py运行了我的应用程序。不幸的是,这导致了以下错误:

ModuleNotFoundError: No module named '__main__.common'; '__main__' is not a package

这个问题的原因是main.py直接由python命令执行,从而成为名为__main__的主模块。如果我们将此信息与使用的相对导入相连接,我们将得到错误消息中的信息:__main__.common。这在Python documentation中解释:

Note that relative imports are based on the name of the current module. Since the name of the main module is always __main__, modules intended for use as the main module of a Python application must always use absolute imports.

当我用pip install .安装我的包并运行它时,它工作得非常好。我还可以在Python控制台中导入mypackage.main模块。所以看起来只有直接运行它才有问题。

绝对进口

让我们按照文档中的建议,将导入语句更改为其他语句:

from common import my_func

如果我们现在试着像以前一样运行这个:python mypackage/main.py,那么它会按预期工作!但是,当您像我一样,在使用pip安装后开发一些需要作为独立命令行工具使用的工具时,有一个警告。我用pip install .安装了我的包,然后试图运行它。。。

ModuleNotFoundError: No module named 'common'

更糟糕的是,当我打开一个Python控制台,尝试手动导入main模块(import mypackage.main)时,我得到了与上面相同的错误。原因很简单:common不再是相对导入,所以Python会尝试在已安装的包中找到它。我们没有这样的包裹,所以失败了。

只有当您创建一个典型的Python应用程序并使用python命令执行时,使用绝对导入的解决方案才能正常工作。

使用包名称导入

还有第三种可能是导入common模块:

from mypackage.common import my_func

这与相对导入方法没有太大区别,只要我们从mypackage的上下文中进行。同样,尝试使用python mypackage/main.py运行此命令的结尾类似:

ModuleNotFoundError: No module named 'mypackage'

这有多烦人,解释器是对的,你没有安装这样的软件包。

解决方案

对于简单的Python应用程序

只要使用绝对进口(没有点),一切都会好的。

用于开发中的可安装Python应用程序

使用相对导入,或者在导入的开头使用包名,因为在安装应用程序时需要这样的导入。在开发中运行这样的模块时,可以使用-m选项执行Python:

-m mod : run library module as a script (terminates option list)

所以不要这样做:python mypackage/main.py

除了md sabuj sarker的回答,还有一个非常好的例子在Python modules documentation

这就是文档中所说的intra-package-references

Note that relative imports are based on the name of the current module. Since the name of the main module is always "__main__", modules intended for use as the main module of a Python application must always use absolute imports.

如果运行python3 moduleA.py3,那么moduleA将用作主模块,因此使用绝对导入看起来是正确的做法。

但是,请注意,如果由于某种原因,包包含与包同名的模块文件(至少在我的Python 3.7上),则此绝对导入(from package.module import something)将失败。因此,举例来说,如果你有(使用OP的例子),它就会失败:

proj/
    __init__.py (empty)
    proj.py (same name as package)
    moduleA.py
    moduleB.py

在这种情况下,您将得到:

ModuleNotFoundError: No module named 'proj.moduleB'; 'proj' is not a package

或者,您可以删除from .moduleB import中的.,如建议的herehere中的.,这似乎是有效的,尽管my PyCharm(2018.2.4)将其标记为“未解析引用”,并且无法自动完成。

相关问题 更多 >

    热门问题