Im Unterverzeichnis aus Quellverzeichnis importieren...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Hallo,

wenn ich folgende Verzeichnisstruktur habe:

Code: Alles auswählen

/home/mutetella/tmp/__init__.py
/home/mutetella/tmp/foo.py
/home/mutetella/tmp/test/__init__.py
/home/mutetella/tmp/test/bla.py
und ich möchte innerhalb `bla.py` `foo` importieren, geht das nur über `sys.path`?

Code: Alles auswählen

import sys
sys.path.append('/home/mutetella/tmp')
import foo
Erscheint mir merkwürdig.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: ``from tmp import foo`` denn `foo` ist ja ein Modul im `tmp`-Paket.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@BlackJack
Das dachte ich eben auch, bekomme aber

Code: Alles auswählen

mutetella@X200 ~/tmp/test
$ python
Python 2.7.6 (default, Jan 11 2014, 14:34:26) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from tmp import foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named tmp
:K
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: Was hier im Suchpfad für Module sein muss ist der Ordner in dem das `tmp/`-Verzeichnis liegt. In Paketverzeichnisse wechseln um dann dort Module zu importieren bring nur Chaos und Verwirrung. Wenn man sich eine Paketstruktur anlegt, dann sollte man sie auch selber respektieren.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@BlackJack
Aber weshalb funktioniert es denn von unten nach oben? Wenn ich innerhalb `/tmp` etwas aus `/test` importieren möchte, muss ich `/tmp` doch auch nicht bekannt machen...?

Mal zu meinem konkreten Problem: Bisher habe ich noch keine wirkliche Paketstruktur. Alle Module (`recurrence.py`, `appointment.py` etc.) liegen im selben Verzeichnis. In diesem Verzeichnis habe ich keine `__init__.py`. Nun scheint es ja aus gutem Grunde gängige Praxis zu sein, Testfunktionen in ein eigenes Verzeichnis zu legen. Wenn ich nun dort eine Funktion habe, die Wiederholungsklassen testet, muss ich `recurrence.py` ja dort importieren. Und genau das macht mir Probleme. Ich hab' mal im python-markdown Quelltext geschaut. Dort wird in `/tests/__init__.py` mit relativen Importen gearbeitet und nichts über `sys.path` bekannt gemacht. Wenn ich das in meiner `/tests/__init__.py` versuche, erhalte ich

Code: Alles auswählen

>>> from .. import recurrence
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Attempted relative import in non-package
Mir scheint, ich verstehe da grundsätzlich etwas nicht. Nur was?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: Wenn Du etwas in ``tmp/`` ausführst, dann ist ``tmp/`` im Suchpfad und damit auch das `test`-Package. Du hast ``tmp/`` also implizit doch bekannt gemacht.

Bei der Ausnahme versuchst Du aus dem Paket `tests` in das übergeordnete Paket zu gehen, was nach Deiner eigenen Aussage nicht existiert.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@BlackJack
Das kann doch nicht wahr sein :? , ich schnall's einfach nicht!!!

Ich habe folgendes:
~/tmp/foo.py
~/tmp/test/bla.py

Weshalb kann ich innerhalb `bla.py` kein ``from .. import foo`` oder (wenn eine `~/tmp/__init__.py` vorhanden) kein ``from tmp import foo`` durchführen?

Ich möchte doch einfach nur in einem Modul eine anderes Modul des übergeordneten Verzeichnisses importieren. Das kann doch so schwer nicht sein... Bin am Verzweifeln!

Stimmt denn überhaupt das Folgende:
  • ``from . import module`` importiert ein Modul aus dem Verzeichnis, innerhalb dessen sich das Modul, das importieren möchte, befindet (aber eigentlich importiere ich doch immer aus diesem Verzeichnis?!)
  • ``from .. import module`` macht dasselbe aus dem übergeordneten Verzeichnis
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@mutetella: egal, wie Du was importierst, die Module müssen existieren. Das heißt:
1. ~/ ist im Suchpfad von Python
2. ~/tmp/__init__.py existiert
dann kannst Du "from tmp import foo" schreiben.
Wenn
3. ~/tmp/test/__init__.py existiert
kannst Du, wenn Du bla als tmp.test.bla importierst, auch "from .. import foo" schreiben, weil .. in der Pakethierarchie eine Ebene nach oben geht, also von tmp.test nach tmp.
Das .. bezieht sich aber auf Pakete und nicht auf Verzeichnisse.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@Sirius3
Also geht das, was ich möchte, tatsächlich nur, wenn ich das entsprechende Verzeichnis über `sys.path` bekannt mache. Ich verstehe dann nur nicht (und deshalb habe ich diesen Thread überhaupt aufgemacht), weshalb in den Test-Modulen von python-markdown nirgends etwas an `sys.path` angehängt wird. Oder wird davon ausgegangen, dass die Tests nach einer Installation ausgeführt werden, die entsprechenden Verzeichnisse also nach Ausführung der setup.py (Zeile 139) in `sys.path` eingetragen sind?
Wenn dem so ist, verstehe ich nicht, weshalb das so gemacht wird. Wenn ich Tests durchführe, gehe ich doch nicht davon aus, dass das zu testende Programm die nötigen Voraussetzungen bereits durch einen Installationsvorgang hat. Ich teste doch in einer "jungfräulichen" Umgebung, bevor das Programm zur Installation kommt?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: Die Tests sollen überprüfen ob das Programm in seinem normalen Zustand so funktioniert wie es soll. Und normalerweise ist es ja installiert. Wenn Du es nicht installiert testest, dann kann es doch durchaus sein, dass Tests fehlschlagen die funktionieren würden wenn es installiert ist. Sieh es nicht als Test ob es funktioniert bevor Du es installierst, sondern als Test ob es funktioniert nach dem es installiert wurde. Was letztlich ja wohl auch wichtiger ist.

Allerdings sind Unit-Tests beim vor oder nach dem installieren sowieso nicht so wichtig, denn hauptsächlich sind es ja Tests für die Entwicklung. Das man die auch als Endanwender nach dem installieren mal laufen lassen kann, sehe ich eher als netten Bonus.

Speziell zu `python-markdown`: Die werden durch das `run-tests.py`-Programm ausgeführt und damit ist das Paket `tests` im Suchpfad, ausserdem werden die Tests selber durch `nose` gesucht und gefunden.
Antworten