ModuleNotFoundError:__main__ 不是包是啥意思?

Posted

技术标签:

【中文标题】ModuleNotFoundError:__main__ 不是包是啥意思?【英文标题】:ModuleNotFoundError: What does it mean __main__ is not a package?ModuleNotFoundError:__main__ 不是包是什么意思? 【发布时间】:2017-06-08 14:09:30 【问题描述】:

我正在尝试从控制台运行一个模块。我的目录结构是这样的:

我正在尝试从problem_set_02 目录运行模块p_03_using_bisection_search.py,使用:

$ python3 p_03_using_bisection_search.py

p_03_using_bisection_search.py里面的代码是:

__author__ = 'm'


from .p_02_paying_debt_off_in_a_year import compute_balance_after


def compute_bounds(balance: float,
                   annual_interest_rate: float) -> (float, float):

    # there is code here, but I have omitted it to save space
    pass


def compute_lowest_payment(balance: float,
                           annual_interest_rate: float) -> float:

    # there is code here, but I have omitted it to save space
    pass    

def main():
    balance = eval(input('Enter the initial balance: '))
    annual_interest_rate = eval(input('Enter the annual interest rate: '))

    lowest_payment = compute_lowest_payment(balance, annual_interest_rate)
    print('Lowest Payment: ' + str(lowest_payment))


if __name__ == '__main__':
    main()

我正在导入p_02_paying_debt_off_in_a_year.py 中的函数,代码是:

__author__ = 'm'


def compute_balance(balance: float,
                    fixed_payment: float,
                    annual_interest_rate: float) -> float:

    # this is code that has been omitted
    pass


def compute_balance_after(balance: float,
                          fixed_payment: float,
                          annual_interest_rate: float,
                          months: int=12) -> float:

    # Omitted code
    pass


def compute_fixed_monthly_payment(balance: float,
                                  annual_interest_rate: float) -> float:

    # omitted code
    pass


def main():
    balance = eval(input('Enter the initial balance: '))
    annual_interest_rate = eval(
        input('Enter the annual interest rate as a decimal: '))
    lowest_payment = compute_fixed_monthly_payment(balance,
                                                   annual_interest_rate)
    print('Lowest Payment: ' + str(lowest_payment))


if __name__ == '__main__':
    main()

我收到以下错误:

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

我不知道如何解决这个问题。我已经尝试添加一个__init__.py 文件,但它仍然无法正常工作。

【问题讨论】:

不是你的问题,但我只是想把它扔在那里:eval(input... 可能不是一个好主意。我只是解析它而不是打开任意代码执行的机会。 我敢打赌 eval(input(... 位是 2to3 建议的。我让它今天对我这样做。很高兴我没有听从它盲目的建议 【参考方案1】:

只需删除相对导入的点并执行以下操作:

from p_02_paying_debt_off_in_a_year import compute_balance_after

【讨论】:

你解决它。为什么即使我添加了__init__.py,相对导入也不起作用? 接受的答案对我不起作用。您能否通过添加一个简约的示例设置来扩展答案? 这对我有用(在一个包内,即在同一文件夹中有一个空的__init__.py),尽管我的 PyCharm (2018.2.4) 将此标记为“未解决的参考”并且无法自动完成导入。 @djvg - 要修复 PyCharm,您可以将根目录标记为源根目录 使用 Python 的导入是令人愤怒的。就像 Python 3、PyCharm 和 MyPy 都在嘲笑我们。 from ..sibling_pkg.nephew import my_function 如何对 PyCharm 有效,但会导致 ValueError: attempted relative import beyond top-level package 和 MyPy Cannot find module named '.sibling_pkg.nephew'(请注意错误中的单个“.”,而不是两个)。然而,from sibling_pkg.nephew import my_function 按预期工作,没有 MyPy 错误,但会导致 PyCharm 错误。【参考方案2】:

我和你有同样的问题。我认为问题在于您在in-package import 中使用了相对导入。您的目录中没有__init__.py。所以就像摩西上面回答的那样导入。

我认为核心问题是当你用点导入时:

from .p_02_paying_debt_off_in_a_year import compute_balance_after

相当于:

from __main__.p_02_paying_debt_off_in_a_year import compute_balance_after

其中__main__ 指的是您当前的模块p_03_using_bisection_search.py


简而言之,解释器不知道您的目录架构。

当解释器进入p_03.py时,脚本等于:

from p_03_using_bisection_search.p_02_paying_debt_off_in_a_year import compute_balance_after

并且p_03_using_bisection_search 不包含任何名为p_02_paying_debt_off_in_a_year 的模块或实例。


所以我想出了一个更清洁的解决方案,而无需更改 python 环境值(在查看了 requests 在相对导入中的操作之后):

目录的主要架构是:

main.py
setup.py
problem_set_02/
   __init__.py
   p01.py
   p02.py
   p03.py

然后写__init__.py:

from .p_02_paying_debt_off_in_a_year import compute_balance_after

这里的 __main____init__ ,它完全是指模块 problem_set_02

那就去main.py:

import problem_set_02

您也可以编写setup.py 来将特定模块添加到环境中。

【讨论】:

【参考方案3】:

如果您已创建目录和子目录,请按照以下步骤操作,请记住所有目录都必须有__init__.py 才能将其识别为目录。

    在您的脚本中,包含import syssys.path,您将能够看到Python 可用的所有路径。您必须能够看到您当前的工作目录。

    现在导入要使用的子目录和相应模块:import subdir.subdir.modulename as abc,现在您可以使用该模块中的方法。

例如,您可以在此屏幕截图中看到我有一个父目录和两个子目录,在第二个子目录下我有模块 CommonFunction。在右侧我的控制台显示在执行sys.path 之后,我可以看到我的工作目录。

【讨论】:

【参考方案4】:

尝试将其运行为:

python3 -m p_03_using_bisection_search

【讨论】:

【参考方案5】:

删除文件开头的点并导入absolute_import

from __future__ import absolute_import

from p_02_paying_debt_off_in_a_year import compute_balance_after

【讨论】:

【参考方案6】:

只需使用 .py 文件所在的主文件夹的名称即可。

from problem_set_02.p_02_paying_debt_off_in_a_year import compute_balance_after

【讨论】:

以上是关于ModuleNotFoundError:__main__ 不是包是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

数据流 flex 模板:ModuleNotFoundError:没有模块名称

从终端运行脚本时出现 ModuleNotFoundError

ModuleNotFoundError: No module named xxx 解决办法

GDB:ModuleNotFoundError:没有名为“_tkinter”的模块

pyenv 失败:ModuleNotFoundError: No module named '_ctypes' 错误

Python - ModuleNotFoundError:没有命名的模块