webentwicklung-frage-antwort-db.com.de

python-Verpackung für relative Importe

Zunächst einmal alles: Es tut mir leid, ich weiß, es gab viele Fragen zu den relativen Importen, aber ich habe einfach keine Lösung gefunden. Wenn möglich möchte ich folgendes Verzeichnislayout verwenden:

myClass/
    __init__.py
    test/
        demo.py
        benchmark.py
        specs.py
    src/
        __init__.py
        myClass.py

Nun sind meine Fragen:

  • Wie importieren die Testdateien aus dem Paket myClass.py ordnungsgemäß?

  • Wie würden Sie das Paket von außen importieren, vorausgesetzt, Sie nehmen myClass als Submodul in libs/myClass oder include/myClass?

Bisher konnte ich dafür keine elegante Lösung finden. Von dem, was ich verstehe Guidos Entscheidung sollte es möglich sein, from ..src import myClass zu tun, aber dies wird ein Fehler sein:

ValueError: Attempted relative import in non-package

Wie es aussieht, behandelt es myClass nicht als Pakete. Lesen der Dokumente :

Die __init__.py-Dateien sind erforderlich, damit Python die Verzeichnisse als Paket enthaltend behandelt.

Es scheint, dass mir etwas fehlt, das angibt, wo sich die Skripts des Pakets befinden. Sollte ich .pth verwenden?

70
eerne

ValueError: Attempted relative import in non-package

Mittel, die Sie versuchen, den relativen Import in dem Modul zu verwenden, das kein Paket ist. Das Problem mit der Datei, die diese from ... import-Anweisung enthält, und nicht mit der Datei, die Sie importieren möchten.

Wenn Sie beispielsweise in Ihren Tests relative Importe durchführen, sollten Sie Ihre Tests als Teil Ihres Pakets definieren. Das heisst 

  1. Hinzufügen von __init__.py zu test /
  2. Führen Sie sie von einem externen Skript aus, z. B. Nosetests

Wenn Sie etwas als python myClass/test/demo.py ausführen, funktionieren relative Importe nicht, da Sie das Demomodul nicht als Paket ausführen. Relative Importe setzen voraus, dass das Modul, das sie verwendet, entweder als Paketmodul from myClass.test.demo import blabla oder mit relativen Import importiert wird.

42
Daniel Kluev

Nach stundenlangem Suchen gestern Abend fand ich die Antwort auf relative Importe in Python !! Oder zumindest eine einfache Lösung. Dies lässt sich am besten beheben, indem die Module von einem anderen Modul aufgerufen werden. Angenommen, Sie möchten, dass demo.pymyClass.py importiert. Im Ordner myClass im Stammverzeichnis der Unterpakete müssen sie über eine Datei verfügen, die die beiden anderen aufruft. Von dem, was ich sammle, wird das Arbeitsverzeichnis immer als __main__ betrachtet. Wenn Sie also den Import von demo.py mit dem demo.py-Skript testen, erhalten Sie diese Fehlermeldung. Um zu zeigen:

Ordnerhierarchie:

myClass/
    main.py #arbitrary name, can be anything
    test/
        __init__.py
        demo.py
    src/
        __init__.py
        myClass.py

myClass.py:

def randomMaths(x):
    a = x * 2
    y = x * a
    return y

demo.py:

from ..src import myClass

def printer():
    print(myClass.randomMaths(42))

main.py:

import test.demo

demo.printer()

Wenn Sie demo.py im Interpreter ausführen, wird ein Fehler generiert, die Ausführung von main.py jedoch nicht. Es ist ein wenig kompliziert, aber es funktioniert: D

27
Sevvy325

Intra-package-referenzen beschreibt, wie myClass von test/* zu ändern ist. Um das Paket von außen zu importieren, sollten Sie den Pfad zur Umgebungsvariablen PYTHONPATH hinzufügen, bevor Sie die Importer-Anwendung ausführen, oder vor dem Importieren die Liste sys.path im Code.

Warum from ..src import myClass fehlschlägt: Wahrscheinlich ist src kein Python-Paket, Sie können von dort aus nicht importieren. Sie sollten es wie oben beschrieben zum Python-Pfad hinzufügen.

0
khachik