ModuleNotFoundError: Co to znaczy __main__ nie jest pakietem?

207

Próbuję uruchomić moduł z konsoli. Struktura mojego katalogu jest następująca:

wprowadź opis zdjęcia tutaj

Próbuję uruchomić moduł p_03_using_bisection_search.pyz problem_set_02katalogu przy użyciu:

$ python3 p_03_using_bisection_search.py

Kod wewnątrz p_03_using_bisection_search.pyjest:

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

Importuję funkcję, w p_02_paying_debt_off_in_a_year.pyktórej znajduje się kod:

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

Otrzymuję następujący błąd:

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

Nie mam pojęcia, jak rozwiązać ten problem. Próbowałem dodać __init__.pyplik, ale nadal nie działa.

lmiguelvargasf
źródło
3
Nie twój problem, ale po prostu chciałem to wyrzucić: eval(input...prawdopodobnie nie jest to świetny pomysł. Po prostu przeanalizuję to, zamiast dać szansę na wykonanie dowolnego kodu.
Carcigenicate
2
Założę się, że ten eval(input(...bit został zasugerowany przez 2to3. Zrobiłem to dzisiaj. Cieszę się, że nie podążam za jego sugestiami, oślepiającymi
ckot

Odpowiedzi:

237

Po prostu usuń kropkę dla importu względnego i wykonaj:

from p_02_paying_debt_off_in_a_year import compute_balance_after
Mojżesz Koledoye
źródło
56
rozwiązujesz to. Dlaczego import względny nie działa, nawet jeśli dodam __init__.py?
lmiguelvargasf
23
Przyjęta odpowiedź nie działa dla mnie. Czy możesz rozszerzyć odpowiedź, dodając minimalistyczną przykładową konfigurację?
Pranasas
13
Działa to dla mnie (w pakiecie, tj. Z pustym __init__.pyw tym samym folderze), chociaż moja PyCharm (2018.2.4) oznacza to jako „nierozstrzygnięte odwołanie” i nie może automatycznie uzupełnić importu.
djvg
33
@djvg - Aby naprawić PyCharm, możesz oznaczyć katalog główny jako źródłowy root
Denis Yakovlev,
12
Praca z importem Pythona jest irytująca. To tak, jakby wszyscy Python 3, PyCharm i MyPy śmiali się na nasz koszt. Jak to from ..sibling_pkg.nephew import my_functionjest ważne dla PyCharm, ale powoduje ValueError: attempted relative import beyond top-level packagei MyPy Cannot find module named '.sibling_pkg.nephew'(zanotuj pojedynczy „.” W błędzie, a nie dwa). Jednak from sibling_pkg.nephew import my_functiondziała zgodnie z przeznaczeniem, nie ma błędu MyPy, ale powoduje błąd PyCharm.
ubiquibacon
85

Mam taki sam problem jak ty. Myślę, że problem polega na tym, że użyłeś importu względnego in-package import. Nie ma __init__.pyw twoim katalogu. Więc po prostu zaimportuj, jak Mojżesz odpowiedział powyżej.

Myślę, że podstawowym problemem jest importowanie za pomocą kropki:

from .p_02_paying_debt_off_in_a_year import compute_balance_after

Jest to równoważne z:

from __main__.p_02_paying_debt_off_in_a_year import compute_balance_after

gdzie __main__odnosi się do bieżącego modułu p_03_using_bisection_search.py.


W skrócie, interpreter nie zna architektury katalogów.

Kiedy interpreter wchodzi p_03.py, skrypt jest równy:

from p_03_using_bisection_search.p_02_paying_debt_off_in_a_year import compute_balance_after

i p_03_using_bisection_searchnie zawiera żadnych wywoływanych modułów ani instancji p_02_paying_debt_off_in_a_year.


Więc wymyśliłem czystsze rozwiązanie bez zmiany cennych elementów środowiska Pythona (po sprawdzeniu, jak żądania działają w przypadku importu względnego):

Główna architektura katalogu to:

main.py

setup.py

---problem_set_02/

------__init__.py

------p01.py

------p02.py

------p03.py

Następnie napisz __init__.py:

from .p_02_paying_debt_off_in_a_year import compute_balance_after

Tutaj __main__jest __init__to dokładnie odnosi się do modułu problem_set_02.

Następnie przejdź do main.py:

import problem_set_02

Możesz także napisać a, setup.pyaby dodać określony moduł do środowiska.

hcnhcn012
źródło
9

Spróbuj uruchomić go jako:

python3 -m p_03_using_bisection_search

Dan Keder
źródło
2

Cześć Wykonaj poniższy krok, rozwiążesz ten problem. Jeśli utworzyłeś katalog i podkatalog, wykonaj poniższe czynności i pamiętaj, że cały katalog musi być __init__.pyrozpoznany jako katalog.

  1. import sysi uruchom sys.path, będziesz mógł zobaczyć wszystkie ścieżki, które są wyszukiwane przez python. Musisz być w stanie zobaczyć swój bieżący katalog roboczy.

  2. Teraz zaimportuj podkatalog i odpowiedni moduł, którego chcesz użyć za pomocą importu, postępuj zgodnie z następującą komendą: import subdir.subdir.modulename as abcteraz możesz korzystać z metod w tym module. ScreenShotforSameIssue

jak widać na tym zrzucie ekranu mam jeden katalog nadrzędny i dwa podkatalogi, a pod drugimi podkatalogami mam moduł == CommonFunction i po prawej stronie po wykonaniu sys.path widzę mój katalog roboczy

Gaurav Singh
źródło
1

Usuń kropkę i zaimportuj absolutny_import na początku pliku

from __future__ import absolute_import

from p_02_paying_debt_off_in_a_year import compute_balance_after
Aminah Nuraini
źródło
1

Wystarczy użyć nazwy głównego folderu, w którym znajduje się plik .py.

from problem_set_02.p_02_paying_debt_off_in_a_year import compute_balance_after
FanBek
źródło