ModuleNotFoundError: что это означает, что __main__ не является пакетом?

Я пытаюсь запустить модуль с консоли. Структура моего каталога такова:

введите описание изображения здесь

Я пытаюсь запустить модуль p_03_using_bisection_search.py из каталога problem_set_02, используя:

$ python3 p_03_using_bisection_search.py

Код внутри p_03_using_bisection_search.pyis:

__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, но он все еще не работает.


person lmiguelvargasf    schedule 23.01.2017    source источник
comment
Не твоя проблема, но я просто хотел ее выбросить: eval(input..., вероятно, не лучшая идея. Я бы просто проанализировал его, вместо того чтобы открывать возможность для выполнения произвольного кода.   -  person Carcigenicate    schedule 24.01.2017
comment
Я готов поспорить, что бит eval(input(... был предложен 2to3. Это случилось со мной сегодня. рад, что я не следую его предложениям вслепую   -  person ckot    schedule 20.06.2018


Ответы (7)


Просто удалите точку для относительного импорта и выполните:

from p_02_paying_debt_off_in_a_year import compute_balance_after
person Moses Koledoye    schedule 23.01.2017
comment
вы решаете это. Почему относительный импорт не работает, даже если я добавлю __init__.py? - person lmiguelvargasf; 24.01.2017
comment
Принятый ответ у меня не работает. Не могли бы вы расширить ответ, добавив минималистичный пример настройки? - person Pranasas; 19.06.2017
comment
из myclass import SomeClass, здесь я получил ошибку для myclass и SomeClass, но все же это сработало для меня. - person Kiran Sk; 19.08.2018
comment
Это работает для меня (внутри пакета, то есть с пустым __init__.py в той же папке), хотя мой PyCharm (2018.2.4) отмечает это как неразрешенную ссылку и не может автоматически завершить импорт. - person djvg; 11.10.2018
comment
@djvg - чтобы исправить PyCharm, вы можете пометить корневой каталог как исходный корень - person Denis Yakovlev; 14.01.2019
comment
Предупреждение: это не удается, если вы создаете entry_point console_script в setup.py при распространении пакета. Кроме того, VSCode не может это проанализировать (хотя это ошибка редактора). - person Anmol Singh Jaggi; 05.04.2019
comment
Работа с импортом 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. - person ubiquibacon; 16.07.2019
comment
Я исправил эту ошибку, не назвав свой основной скрипт тем же именем, что и его родительский каталог. У меня был мой основной скрипт app.py в папке app, то есть app/app.py. В нем была строка import app.lib, предназначенная для импорта модуля app/lib.py. Поднимает ModuleNotFoundError: No module named 'app.lib'; 'app' is not a package. Исправлено переименованием app/app.py в app/blabla.py. - person wjakobw; 13.02.2020
comment
Расширение комментария от @DenisYakovlev: чтобы пометить каталог как корень источников в PyCharm, просто щелкните правой кнопкой мыши, Пометить каталог как, Корень источников. - person vlz; 12.03.2020
comment
@ubiquibacon, возможно, у вас никогда не будет несчастья пытаться работать с зависимостями для любого среднего / большого приложения. - person weberc2; 27.03.2020
comment
@MosesKoledoye, объясните, пожалуйста, почему удаление точки работает, а не иначе. Спасибо - person nish; 14.04.2020

У меня такая же проблема, как и у вас. Думаю, проблема в том, что вы использовали относительный импорт в 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 (после того, как я посмотрел, как запросы делать в относительном импорте):

Основная архитектура каталога:

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, чтобы добавить конкретный модуль в среду.

person hcnhcn012    schedule 29.09.2017

Попробуйте запустить его как:

python3 -m p_03_using_bisection_search

person Dan Keder    schedule 18.07.2018

Удалите точку и импортируйте absolute_import в начало вашего файла

from __future__ import absolute_import

from p_02_paying_debt_off_in_a_year import compute_balance_after
person Aminah Nuraini    schedule 05.09.2019

Если вы создали каталог и подкаталог, выполните следующие действия и помните, что во всех каталогах должен быть __init__.py, чтобы его можно было распознать как каталог.

  1. Включите в свой сценарий import sys и sys.path, и вы увидите все пути, доступные для Python. Вы должны видеть свой текущий рабочий каталог.

  2. Теперь импортируйте подкаталог и соответствующий модуль, который вы хотите использовать, используя: import subdir.subdir.modulename as abc, и теперь вы можете использовать методы в этом модуле.

введите описание изображения здесь

В качестве примера вы можете видеть на этом снимке экрана, что у меня есть один родительский каталог и два подкаталога, а во вторых подкаталогах у меня есть модуль CommonFunction. Справа моя консоль показывает, что после выполнения sys.path я вижу свой рабочий каталог.

person Gaurav Singh    schedule 21.10.2017

Просто используйте имя основной папки, в которой находится файл .py.

from problem_set_02.p_02_paying_debt_off_in_a_year import compute_balance_after
person FanBek    schedule 03.05.2020

Проблема все еще не решена после удаления '.', Затем она указывает на ошибку в моей папке. Когда я впервые добавил эту папку, я перезапустил PyCharm, и проблема была автоматически решена.

person Ramgopal    schedule 09.02.2021