71 Stimmen

python-Paketierung für relative Importe

Zunächst einmal: Es tut mir leid, ich weiß, dass es schon viele Fragen zu relativen Importen gab, aber ich habe einfach keine Lösung gefunden. Wenn möglich, würde ich gerne die folgende Verzeichnisstruktur verwenden:

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

Jetzt sind meine Fragen:

  • Wie importieren die Testdateien aus dem Paket richtig myClass.py?

  • 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 keine elegante Lösung für dieses Problem finden. Soweit ich das verstehe Guidos Entscheidung sollte es möglich sein, Folgendes zu tun from ..src import myClass aber dies führt zu einem Fehler:

ValueError: Attempted relative import in non-package

Das sieht so aus, als ob es myClass nicht als Pakete behandelt. Lesen der Dokumente :

Die __init__.py-Dateien sind erforderlich, damit Python die Verzeichnisse als Pakete behandeln kann;

Es scheint mir etwas zu fehlen, das angibt, wo die Skripte des Pakets sind, sollte ich .pth verwenden?

42voto

Daniel Kluev Punkte 10335

ValueError: Attempted relative import in non-package

Das bedeutet, dass Sie versuchen, einen relativen Import in einem Modul zu verwenden, das kein Paket ist. Sein Problem mit der Datei, die dies hat from ... import Anweisung und nicht die Datei, die Sie zu importieren versuchen.

Wenn Sie also zum Beispiel relative Importe in Ihren Tests durchführen, sollten Sie Ihre Tests zu einem Teil Ihres Pakets machen. Das bedeutet

  1. Hinzufügen von __init__.py zu testen/
  2. Sie werden von einem externen Skript wie nosetests ausgeführt.

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

28voto

Sevvy325 Punkte 527

Nach stundenlangem Suchen habe ich gestern Abend die Antwort auf relative Importe in Python gefunden!!! Oder zumindest eine einfache Lösung. Der beste Weg, dies zu beheben, ist, die Module von einem anderen Modul aus aufzurufen. Sagen wir also, Sie wollen demo.py zu importieren myClass.py . In der myClass im Wurzelverzeichnis der Unterpakete müssen sie eine Datei haben, die die beiden anderen aufruft. Soweit ich weiß, wird das Arbeitsverzeichnis immer als __main__ Wenn Sie also den Import von demo.py mit dem demo.py Skript, erhalten Sie diesen Fehler. Zur Veranschaulichung:

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, wird ein Fehler erzeugt, aber die Ausführung von main.py wird nicht. Es ist ein wenig verworren, aber es funktioniert :D

0voto

khachik Punkte 27252

Intra-Paket-Referenzen beschreibt, wie man myClass de test/* . Um das Paket von außen zu importieren, sollten Sie seinen Pfad zu PYTHONPATH Umgebungsvariable, bevor Sie die Importer-Anwendung ausführen, oder um sys.path Liste in den Code einfügen, bevor sie importiert wird.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X