Seite 1 von 1
Packageinterne Importe bei Aufruf von außen
Verfasst: Montag 20. Juni 2011, 11:16
von yaem
Schon wieder eine Anfängerfrage...
Ich hab ein Problem mit packages. Ich habe ein Verzeichnis namens "package" mit einer leeren "__init__.py" und zwei Modulen "one.py" und "two.py":
one.py:
Code: Alles auswählen
import two
def say(what):
print("One says: ", what)
two.say(what)
two.py:
Im gleichen Ordner in dem auch "package" liegt hab ich eine "main.py":
Fehlermeldung:
> "python" "D:\Dokumente und Einstellungen\Me\Eigene Dateien\Programming\Applications\Python\Test\main.py"
Traceback (most recent call last):
File "D:\Dokumente und Einstellungen\Me\Eigene Dateien\Programming\Applications\Python\Test\main.py", line 1, in <module>
import package.one
File "D:\Dokumente und Einstellungen\Me\Eigene Dateien\Programming\Applications\Python\Test\package\one.py", line 1, in <module>
import two
ImportError: No module named two
"two.py" kann also scheints nicht gefunden werden. Wenn ich aber direkt die Datei "one.py" um die Zeile "say("hello")" ergänze und ausführe klappts wunderbar. Wo liegt mein Fehler?
Re: Packageinterne Importe bei Aufruf von außen
Verfasst: Montag 20. Juni 2011, 13:41
von BlackJack
@yaem: Ich nehme mal an Du startest den Test dann innerhalb von ``./package/`` — dann ist das Verzeichnis das aktuelle Arbeitsverzeichnis und das ist in `sys.path` enthalten. Wenn Du `main.py` oberhalb von ``./package/`` startest, dann ist `two.py` nicht im aktuellen Arbeitsverzeichnis, kann mit ``import foo`` also auch nicht gefunden werden. Du musst das entweder absolut oder relativ importieren. Ich bevorzuge absolut. Also ``from package import two``.
Re: Packageinterne Importe bei Aufruf von außen
Verfasst: Montag 20. Juni 2011, 14:15
von yaem
Mmh... Um Misverständnissen vorzubeugen, meine Verzeichnisstruktur sieht so aus:
main.py
package/
--> __init__.py
--> one.py
--> two.py
Ich habe jetzt mal in "one.py" anstatt "import two" "from package import two" geschrieben. Jetzt kann ich zwar "main.py" wie erwartet ausführen, allerdings vermeldet "one.py" beim direkten Ausführen logischerweise, dass ein Package namens "package" nicht existiert.
Die dritte Möglichkeit "from . import two" gibt dagegen die interessante Meldung: "ValueError: Attempted relative import in non-package"
Warum? "one.py" ist doch, dank __init__.py, eindeutig in einem package und müsste das doch auch erkennen?!?
Rein von der Logik her muss doch auch "import two" gehen, oder?
Vor allem beunruhigt mich, dass "from . import two" diese seltsame Fehlermeldung ausgiebt... Hab ich da wieder in meinem Editor was falsch eingestellt?!?
Ich möchte, dass "one.py" sozusagen die Zugriffschnittstelle für das package "package" ist und alle weiteren Module "two.py..." vor dem Benutzer des Packages verborgen bleiben.
Re: Packageinterne Importe bei Aufruf von außen
Verfasst: Montag 20. Juni 2011, 15:23
von BlackJack
@yaem: Das ist nur logisch wenn Du vorher in das Package-Verzeichnis hinein wechselst. Wenn Python das Package finden kann, dann kannst Du auch das Modul in dem Package direkt ausführen.
Re: Packageinterne Importe bei Aufruf von außen
Verfasst: Montag 20. Juni 2011, 15:40
von yaem
Häng ich da etwa zu sehr in meinem C/C++ Denken fest? Wenn da irgendein Header "#include "./another.h"" verlangt würde doch als allererstes im Verzeichnis des Headers gesucht werden. Bei Python ist das nicht so?
Wenn Python das Package finden kann, dann kannst Du auch das Modul in dem Package direkt ausführen.
Ich bin mir nicht sicher, ob ich verstehe, was du da sagst.
Die Varianten(in "package/one.py")...
"from package import two" und
"from . import two"
...funktionieren, wenn "one.py" über "main.py" ausgeführt wird. Aber dann nicht, wenn ich Code (zum Beispiel zu Testzwecken) direkt im Modul ausführe.
Da geht dann nur....
"import two"
Gibt es eine Möglichkeit beide Fälle - also direktes Ausführen im Modul und ausführen über Import - zu verbinden?
Gut, auf alle Fälle schein ich erstmal unbefriedigend um das Problem herumzukommen... Ich danke Dir!

Re: Packageinterne Importe bei Aufruf von außen
Verfasst: Montag 20. Juni 2011, 15:51
von BlackJack
Wenn Du den relativen import versuchst, dann wird geschaut das `.` das Paket `package` ist, aber dieses Paket gibt es nicht im Sinne von: es kann nicht mit ``import package`` importiert werden. Wäre ja komisch/inkonsistent wenn das relativ ginge, absolut aber nicht. ``from package import two`` funktioniert auch wenn Du `one.py` direkt ausführst *solange `package` importierbar ist*! Geh mal in das Verzeichnis wo `main.py` liegt und führe `one.py` *von dort aus* aus.