2010-12-03 17 views
70

Zunächst einmal: Es tut mir leid, ich weiß, es gab viele Fragen über relative Importe, aber ich habe einfach keine Lösung gefunden. Wenn möglich, würde Ich mag die folgende Verzeichnisstruktur verwenden:Python Verpackung für relative Importe

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

Nun meine Fragen sind:

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

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

Bis jetzt konnte ich keine elegante Lösung dafür finden. Von dem, was ich Guido's Decision verstehen sollte es möglich sein from ..src import myClass zu tun, aber dieser Fehler:

ValueError: Attempted relative import in non-package

Welche, da sie als Pakete nicht behandeln myClass aussieht. Reading the docs:

The __init__.py files are required to make Python treat the directories as containing packages;

Es scheint, ich etwas fehle, das in dem die Skripte des Pakets spezifiziert sind, sollte ich .pth benutzen?

+6

@Brent Newey, ja Sie haben Recht, relative Importe scheint ein laufendes Thema zu sein und nachdem ich einige Antworten gelesen hatte, fühlte ich immer noch den Drang, meine Situation zu beschreiben. Nach dem Zeigen dieses q empfahlen einige Leute auf dem #python IRC-Kanal eine flache Verzeichnisstruktur: "Viele Leute widerstehen der Art, wie Python Verzeichnisse und Dateien für semantische Namespace-Informationen verwenden will. Es ist am besten, nachzugeben und zu tun was Python will. " http://jcalderone.livejournal.com/39794.html – eerne

+8

Könnte jemand einen Link zu einigen realen Paketen mit einem exemplarischen Verzeichnislayout bereitstellen oder einigen Konventionen folgen? (Idealerweise auf github) – eerne

+1

Gibt es '___ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _? 'ValueError: Versuchter relativer Import in Nicht-Paket' könnte damit zusammenhängen. – jfs

Antwort

0

Intra-package-references beschreibt, wie zu myClass von test/*. Um das Paket von außerhalb zu importieren, müssen Sie den Pfad zur Umgebungsvariablen PYTHONPATH hinzufügen, bevor Sie die Importanwendung ausführen, oder sys.path im Code vor dem Importieren auflisten.

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

+0

Relative Importe sind die ganze Zeit. Viele Pakete haben kleinere Unterpakete mit darin und sind auf relative Importe angewiesen. Das OP fragt nicht, wie externe Pakete referenziert werden sollen. Er fragt, wie ein anderes Unterpaket innerhalb eines Pakets referenziert werden soll. – cstrutton

41

ValueError: Attempted relative import in non-package

Bedeutet, dass Sie versuchen, relativen Import in dem Modul zu verwenden, das kein Paket ist. Sein Problem mit der Datei, die diese from ... import-Anweisung hat, und nicht die Datei, die Sie importieren möchten.

Wenn Sie zum Beispiel relative Importe in Ihren Tests durchführen, sollten Sie Ihre Tests als Teil Ihres Pakets betrachten. Das bedeutet,

  1. __init__.py Hinzufügen/
  2. sie von einem außerhalb Skript zu testen Rennen, wie nosetests

Wenn Sie etwas wie python myClass/test/demo.py ausführen, wird relativ Importe zu nicht funktionieren, da Sie Demo-Modul ausgeführt werden nicht als Paket. Relative Importe erfordern, dass das Modul, das sie verwendet, entweder selbst als Paketmodul, from myClass.test.demo import blabla oder mit relativem Import importiert wird.

25

Nach Stunden der Suche letzte Nacht fand ich die Antwort auf die relativen Importe in Python !! Oder zumindest eine einfache Lösung. Der beste Weg, dies zu beheben, sind die Module, die von einem anderen Modul aufgerufen werden. Also sagen Sie wollen demo.py zu importieren myClass.py in den MyClass-Ordner an der Wurzel der Sub-Pakete Spielzeug muss eine Datei haben, die die anderen beiden anruft.Von dem, was ich erfahre, wird das Arbeitsverzeichnis immer als Haupt angesehen. Wenn Sie also den Import von demo.py mit dem demo.py Skript testen, werden Sie diesen Fehler erhalten. Zur Veranschaulichung:

Ordner hierarcy:

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 im Interpreter demo.py ausführen, erzeugen Sie einen Fehler, aber main.py wird nicht ausgeführt. Es ist ein wenig verschachtelt, aber es funktioniert: D

+3

Ich benutze Python 2.7 und ich habe nur den obigen Code, um mit drei Dingen zu arbeiten. Zuerst habe ich auf der Ebene, auf der main.py steht, ein "__init __. Py" hinzugefügt. Zweitens habe ich demo.printer() zu 'test.demo.printer()' gewechselt. Drittens änderte ich das Verzeichnis über main.py und führte 'python -m myClass.main' aus. Ansonsten war das eine sehr hilfreiche Antwort für mich. :) – Paul

Verwandte Themen