Import Probleme

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
Apophis
User
Beiträge: 6
Registriert: Mittwoch 19. Mai 2010, 09:21

Hallo Leute,

ich hab ein Problem mit Import. Ich schreibe an einem Programm, für das ich 1 Verzeichnis für die Quelltexte habe und 1 Verzeichnis für die Tests. Das sieht in etwa so aus:

Code: Alles auswählen

-root/
  |
  +-src/
  | |
  | +-pkg1/
  |   |
  |   +-pkg2/
  |     |
  |     --modulA
  |
  +-tests/
    |
    +-pkg1/
      |
      +-pkg2/
      |  |
      |  --modulATest
      |  --testHelper1
      |
      +testHelper/
        |
        --testHelper2
In modulATest hab ich bis jetzt folgendes

Code: Alles auswählen

from pkg1.pkg2 import modulA
import testHelper1
Das funktioniert so auch ohne Probleme. Jetzt möchte ich aber testHelper1 in das Paket testHelper verschieben, also dort wo testHelper2 ist, um es auch in anderen Paketen zu nutzen. Also müsste es dann in modulATest folgendermaßen heißen:

Code: Alles auswählen

from pkg1.pkg2 import modulA
from pkg1.testHelper import testHelper1
Das funktioniert aber nicht. Ich bekomme folgenden Fehler:

Code: Alles auswählen

ImportError: cannot import name testHelper1
anscheinend kann ich aus dem tests/ Verzeichnis nur Module importieren die im gleichen Paket liegen. Hat jemand eine Idee woran das liegen könnte?
Ich verwende Python Version 2.6.5 auf Ubuntu 10.4.
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

du hast bestimmt irgendwo dein sys.path modifiziert? Du hast zwei mal ein ``pkg1`` ...
Apophis
User
Beiträge: 6
Registriert: Mittwoch 19. Mai 2010, 09:21

Das ich 2 mal pkg1 habe ist Absicht. Ich will den Test für ein Modul im gleichen Package haben wie das zu testende Modul. So ist einfacher ersichtlich welcher Test zu welchen Modul gehört. Damit ich die Tests in der Release Version schnell ausfiltern kann, habe ich 2 Quelltextverzeichnise gemacht.
Ich verwende übrigens pydev, eine Python Entwicklungsumgebung für Eclipse. Dort habe ich die Verzeichnisse src/ und tests/ als Quelltextverzeichnisse markiert.

Edit: sys.path wird durch das Programm nicht modifiziert
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

ich kenne mich mit pydev nicht aus, aber dein python wird wahrscheinlich erkennen: in src/ ist ein Modul pkg1, suche dort nach testHelper1 und dort findet er es natürlich nicht.

Du müsstest also vom root Verzeichnis ausgehen (und dieses in dein sys.path einfügen) und src und tests auch mit einer __init__.py versehen:

Code: Alles auswählen

from tests.pkg1.testHelper import testHelper1
Apophis
User
Beiträge: 6
Registriert: Mittwoch 19. Mai 2010, 09:21

Ich hab jetzt in modulATest einfach mal folgendes reingeschrieben

Code: Alles auswählen

import sys
print sys.path
Das Modul liegt im Paket pycq.tasks. Das Root Verzeichnis ist in dem Fall "/home/raik/Programmieren/Eclipse_Workspace/pycq". Das (gekürzte) Ergebnis sieht wie folgt aus:

Code: Alles auswählen

[[...],'/home/raik/Programmieren/Eclipse_Workspace/pycq/src', '/home/raik/Programmieren/Eclipse_Workspace/pycq/tests', [...] '/home/raik/Programmieren/Eclipse_Workspace/pycq/tests/pycq/tasks']
Eigentlich sollte das doch richtig sein oder?
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

nein, weil nun "src" vor "tests" ist und dort auch pkg1 aber nicht testHelper enthalten ist. Entweder du stellst das "tests" vor das "src" oder du machst es von "root" aus.
BlackJack

@Apophis: Das Du zwei Pakete mit dem gleichen Namen hast mag so gewollt sein, geht aber in Python nicht. Es ist nicht so wie in Java wo der Inhalt von gleichnamigen Paketstrukturen in parallelen Verzeichnishierarchien automagisch ge"merge"t wird. Das würde auch interessante Probleme mit sich bringen was zum Beispiel die Ausführungsreihenfolge von `__init__.py`\s angeht.

Das Du Deinen realen `sys.path` und eine fiktive Paketstruktur zeigst, hilft nicht so richtig. Ich mag jetzt jedenfalls nicht raten wie die genau zusammenhängen.

Und wenn Du Verzeichnisstrukturen zeigst, solltest Du auch immer angeben wo tatsächlich eine `__init__.py` liegt, damit man weiss was Paket ist und was nur Verzeichnis. Und nur die Verzeichnisse direkt oberhalb von einem Paket sollten in `sys.path` auftauchen. Wenn da Verzeichnisse innherhalb von Paketen drin stehen, fängt es an komisch zu riechen.
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

@ BlackJack: so schön verständlich kann man es natürlich auch formulieren... :wink:
Apophis
User
Beiträge: 6
Registriert: Mittwoch 19. Mai 2010, 09:21

BlackJack hat geschrieben:@Apophis: Das Du zwei Pakete mit dem gleichen Namen hast mag so gewollt sein, geht aber in Python nicht. [...]
Das ist ärgerlich, aber gut zu wissen. :(
Ich hab bis jetzt tatsächlich mehr mit Java zu tun gehabt.
BlackJack hat geschrieben:Das Du Deinen realen `sys.path` und eine fiktive Paketstruktur zeigst, hilft nicht so richtig. Ich mag jetzt jedenfalls nicht raten wie die genau zusammenhängen.
Ich wollte da nicht zu viel an der Ausgabe drin rum schreiben um nicht irgendwelche Fehler rein zu machen und noch mehr Verwirrung zu stiften. Deswegen hab ich mich entschieden lieber das original zu posten und zu versuchen zu erklären wie das in mein Beispiel passt.
BlackJack hat geschrieben:[...]Und nur die Verzeichnisse direkt oberhalb von einem Paket sollten in `sys.path` auftauchen. Wenn da Verzeichnisse innherhalb von Paketen drin stehen, fängt es an komisch zu riechen.
Das fand ich ehrlich gesagt auch komisch. Das muss wohl ein Problem mit pydev sein. Explizit in den Path aufgenommen habe ich das jedenfalls nicht.

Ich danke euch für eure Hilfe. Wie würdet ihr das Problem lösen? Wenn ich jetzt im Hauptpaket für das Programm ein Unterpaket für tests machen würde und dort nochmal die eigentliche Pakethierachie abbilden würde, bekomme ich irgenwie nen riesen Paketbaum. Habt ihr da ne Idee wie es besser geht?
BlackJack

@Apophis: Du könntest `tests` zu einem Paket machen, dann wären beide Strukturen getrennt.
Apophis
User
Beiträge: 6
Registriert: Mittwoch 19. Mai 2010, 09:21

BlackJack hat geschrieben:@Apophis: Du könntest `tests` zu einem Paket machen, dann wären beide Strukturen getrennt.
Mein Hauptpaket ist "pycq". Ich hab mein Paket für tests jetzt "pycq_tests" genannt. Nur tests ist mir zu allgemein.
Antworten