2010-11-14 23 views
27

Hey alle - ich ziehe meine Haare mit relativen Einfuhren in Python. Ich habe die Dokumentation 30 Mal gelesen und zahlreiche Beiträge hier auf SO und anderen Foren - scheint immer noch nicht zu funktionieren.Relative Importe in Python

Meine Verzeichnisstruktur sieht derzeit wie diese

src/ 
    __init__.py 
    main.py 
    components/ 
     __init__.py 
     expander.py 
     language_id.py 
    utilities/ 
     __init__.py 
     functions.py 

I expander.py und language_id.py wollen Zugriff auf die Funktionen Modul zu haben. Ich führe python main.py aus, das mit den Komponenten components.expander import * und components.language_id import * gut auf die Module zugreift.

jedoch der Code innerhalb Expander und language_id, um das Funktionsmodul zugreifen:

from ..utilities.functions import * 

erhalte ich diesen Fehler:

ValueError: Attempted relative import beyond toplevel package 

Ich habe über sie ein paar Mal gegangen und es scheint Befolgen Sie die Dokumentation. Hat jemand eine Vorstellung davon, was hier schief läuft?

+8

Sie haben die Lösung bereits gefunden, aber um zu erklären, warum sie benötigt wird: Das Paket sollte vollständig eigenständig sein. Es behandelt src/nicht als Paket, wenn Sie main.py darin ausführen. –

Antwort

21

Nevermind, ich löste es:

src/ 
    main.py 
    mod/ 
     __init__.py 
     components/ 
      __init__.py 
      expander.py 
      language_id.py 
     utilities/ 
      __init__.py 
      functions.py 

main.py bezieht sich dann auf die Subpackages als:

from mod.components.expander import * 
from mod.utilities.functions import * 

expander.py und language_id.py Zugang haben mit functions.py:

from ..utilities.functions import * 

Aber die interessante Sache ist, dass ich eine Textdatei innerhalb des Komponentenverzeichnisses hatte, das expander.py uns es. Zur Laufzeit konnte die Datei jedoch nicht gefunden werden, obwohl sie sich im selben Verzeichnis befand. Ich habe die Textdatei in das gleiche Verzeichnis wie main.py verschoben und es hat funktioniert. Scheint kontraintuitiv.

+13

Alle neuen Module importieren Zeug ist gebrochen und nicht intuitiv. –

+3

Das Öffnen von Textdateien funktioniert von dem Arbeitsverzeichnis, in dem Sie das Programm gestartet haben, während das Importieren relativ zum Speicherort des Skripts ist. Sie können \ _ \ _ file \ _ \ _ in einem Modul verwenden, um seinen Pfad zu finden, und damit auf Dinge im selben Verzeichnis verweisen, obwohl es nicht sehr elegant ist. Wenn es sich bei der Textdatei um statische Daten für das Programm handelt, ist es möglicherweise einfacher, sie in ein Python-Modul umzuwandeln und zu importieren. –

+1

Sie können 'pkgutil.get_data()' (http://docs.python.org/library/pkgutil#pkgutil.get_data) verwenden, um Dateien mithilfe des Modulnamensbereichs abzurufen, um sie zu finden. Zum Beispiel wird 'raw_data = pkgutil.get_data ('mod.components', 'data.txt')' die rohen Binärdaten aus der Datei abrufen. – ncoghlan