ModuleNotFoundError: Що означає __main__ не пакет?


207

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

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

Я намагаюся запустити модуль p_03_using_bisection_search.pyіз problem_set_02каталогу, використовуючи:

$ 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файл, але він все ще не працює.


3
Не ваше питання, але я просто хотів його викинути туди: eval(input...напевно, це не чудова ідея. Я б просто проаналізував це замість того, щоб відкрити можливість для довільного виконання коду.
Carcigenicate

2
Я б eval(input(...сказав, що цей біт був запропонований 2to3. Я мав це зробити це мені сьогодні. радий, що я не дотримуюся її пропозицій засліплюючи
ckot

Відповіді:


237

Просто видаліть крапку для відносного імпорту та зробіть:

from p_02_paying_debt_off_in_a_year import compute_balance_after

56
ви вирішуєте це. Чому відносний імпорт не працює, навіть якщо я додаю __init__.py?
lmiguelvargasf

23
Прийнята відповідь не працює для мене. Чи можете ви розширити відповідь, додавши мінімалістичний приклад налаштування?
Пранасас

13
Це працює для мене (всередині пакета, тобто з порожнім __init__.pyу тій самій папці), хоча мій PyCharm (2018.2.4) позначає це як "Невирішене посилання" і не може автоматично завершити імпорт.
djvg

33
@djvg - Щоб виправити PyCharm, ви можете позначити кореневий каталог як вихідний корінь
Денис Яковлев

12
Робота з імпортом 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.
ubiquibacon

85

У мене те саме питання, що і ви. Я думаю, проблема полягає в тому, що ви використовували відносний імпорт у 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

Ви також можете написати a, setup.pyщоб додати певний модуль до середовища.



2

Привіт Будь ласка, дотримуйтесь нижче кроку, ви вирішите цю проблему. Якщо ви створили каталог та підкаталог, виконайте наведені нижче дії, і пам’ятайте, що весь каталог повинен мати його, __init__.pyщоб визнати його каталогом.

  1. import sysі запустивши sys.path, ви зможете побачити увесь шлях, який шукається python. Ви повинні мати можливість бачити поточний робочий каталог.

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

як ви бачите на цьому скріншоті, я маю один батьківський каталог і два підкаталоги, а під другими підкаталогами у мене є модуль == CommonFunction, і ви бачите праву частину після виконання sys.path, я можу побачити свою робочу директорію


1

Видаліть крапку та імпортуйте абсолютний імпорт на початку файлу

from __future__ import absolute_import

from p_02_paying_debt_off_in_a_year import compute_balance_after

1

Просто скористайтеся назвою головної папки, в якій знаходиться файл .py.

from problem_set_02.p_02_paying_debt_off_in_a_year import compute_balance_after
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.