ModuleNotFoundError: Was bedeutet es, dass __main__ kein Paket ist?

206

Ich versuche, ein Modul über die Konsole auszuführen. Die Struktur meines Verzeichnisses ist folgende:

Geben Sie hier die Bildbeschreibung ein

Ich versuche, das Modul p_03_using_bisection_search.pyaus dem problem_set_02Verzeichnis auszuführen , indem ich Folgendes verwende:

$ python3 p_03_using_bisection_search.py

Der Code darin p_03_using_bisection_search.pyist:

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

Ich importiere eine Funktion, in p_02_paying_debt_off_in_a_year.pyder sich Code befindet:

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

Ich erhalte die folgende Fehlermeldung:

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

Ich habe keine Ahnung, wie ich dieses Problem lösen soll. Ich habe versucht, eine __init__.pyDatei hinzuzufügen , aber es funktioniert immer noch nicht.

lmiguelvargasf
quelle
3
Nicht dein Problem, aber ich wollte es einfach da rauswerfen: eval(input...wahrscheinlich keine großartige Idee. Ich würde es nur analysieren, anstatt die Möglichkeit für die Ausführung von willkürlichem Code zu eröffnen.
Carcigenicate
2
Ich würde wetten, dass dieses eval(input(...Bit von 2to3 vorgeschlagen wurde. Ich habe es mir heute antun lassen. Ich bin froh, dass ich den Vorschlägen nicht folge. Blindling
ckot

Antworten:

236

Entfernen Sie einfach den Punkt für den relativen Import und gehen Sie wie folgt vor:

from p_02_paying_debt_off_in_a_year import compute_balance_after
Moses Koledoye
quelle
56
Sie lösen es. Warum funktioniert der relative Import nicht, auch wenn ich hinzufüge __init__.py?
lmiguelvargasf
23
Die akzeptierte Antwort funktioniert bei mir nicht. Könnten Sie die Antwort möglicherweise erweitern, indem Sie ein minimalistisches Beispiel-Setup hinzufügen?
Pranasas
13
Dies funktioniert für mich (innerhalb eines Pakets, dh mit einem leeren __init__.pyOrdner im selben Ordner), obwohl mein PyCharm (2018.2.4) dies als "ungelöste Referenz" markiert und den Import nicht automatisch vervollständigt.
DJVG
33
@djvg - Um PyCharm zu reparieren, können Sie Stammverzeichnis als Quellstamm markieren
Denis Yakovlev
12
Die Arbeit mit Pythons Importen ist ärgerlich. Es ist, als ob Python 3, PyCharm und MyPy alle auf unsere Kosten lachen. Wie kommt es, dass from ..sibling_pkg.nephew import my_functionPyCharm gültig ist, aber zu ValueError: attempted relative import beyond top-level packageund MyPy führt Cannot find module named '.sibling_pkg.nephew'(beachten Sie ein einzelnes "." Im Fehler, nicht zwei). Funktioniert jedoch from sibling_pkg.nephew import my_functionwie beabsichtigt, hat keinen MyPy-Fehler, führt jedoch zu einem PyCharm-Fehler.
Ubiquibacon
85

Ich habe das gleiche Problem wie Sie. Ich denke, das Problem ist, dass Sie relativen Import in verwendet haben in-package import. Es gibt keine __init__.pyin Ihrem Verzeichnis. Also einfach importieren, wie Moses oben geantwortet hat.

Das Kernproblem, denke ich, ist, wenn Sie mit einem Punkt importieren:

from .p_02_paying_debt_off_in_a_year import compute_balance_after

Es ist äquivalent zu:

from __main__.p_02_paying_debt_off_in_a_year import compute_balance_after

wo __main__bezieht sich auf Ihr aktuelles Modul p_03_using_bisection_search.py.


Kurz gesagt, der Interpreter kennt Ihre Verzeichnisarchitektur nicht.

Wenn der Dolmetscher einsteigt p_03.py, entspricht das Skript:

from p_03_using_bisection_search.p_02_paying_debt_off_in_a_year import compute_balance_after

und p_03_using_bisection_searchenthält keine aufgerufenen Module oder Instanzen p_02_paying_debt_off_in_a_year.


Also habe ich eine sauberere Lösung gefunden, ohne die Wertsachen der Python-Umgebung zu ändern (nachdem ich nachgesehen habe, wie sich Anfragen beim relativen Import verhalten):

Die Hauptarchitektur des Verzeichnisses ist:

main.py

setup.py

--- ---.problem_set_02/

------ ------.__init__.py

------ ------.p01.py

------ ------.p02.py

------ ------.p03.py

Dann schreiben Sie in __init__.py:

from .p_02_paying_debt_off_in_a_year import compute_balance_after

Hier __main__ist__init__ , bezieht er sich genau an das Modulproblem_set_02 .

Dann gehen Sie zu main.py:

import problem_set_02

Sie können auch ein schreiben setup.py, um der Umgebung ein bestimmtes Modul hinzuzufügen.

hcnhcn012
quelle
9

Versuchen Sie es wie folgt auszuführen:

python3 -m p_03_using_bisection_search

Dan Keder
quelle
2

Hallo Bitte folgen Sie dem folgenden Schritt, Sie werden dieses Problem beheben. Wenn Sie ein Verzeichnis und ein Unterverzeichnis erstellt haben __init__.py, gehen Sie wie folgt vor und beachten Sie, dass alle Verzeichnisse als Verzeichnis erkannt werden müssen .

  1. import sysund ausführen sys.path, können Sie alle Pfade sehen, die von Python gesucht werden. Sie müssen in der Lage sein, Ihr aktuelles Arbeitsverzeichnis zu sehen.

  2. Importieren Sie nun das Unterverzeichnis und das entsprechende Modul, das Sie mit import verwenden möchten, und folgen Sie diesem Befehl: import subdir.subdir.modulename as abcJetzt können Sie die Methoden in diesem Modul verwenden. ScreenShotforSameIssue

Wie Sie in diesem Screenshot sehen können, habe ich ein übergeordnetes Verzeichnis und zwei Unterverzeichnisse und unter den zweiten Unterverzeichnissen habe ich das Modul == CommonFunction und Sie sehen die rechte Seite nach der Ausführung von sys.path. Ich kann mein Arbeitsverzeichnis sehen

Gaurav Singh
quelle
1

Entfernen Sie den Punkt und importieren Sie absolute_import am Anfang Ihrer Datei

from __future__ import absolute_import

from p_02_paying_debt_off_in_a_year import compute_balance_after
Aminah Nuraini
quelle
1

Verwenden Sie einfach den Namen des Hauptordners, in dem sich die .py-Datei befindet.

from problem_set_02.p_02_paying_debt_off_in_a_year import compute_balance_after
FanBek
quelle