Module aus höheren Verzeichnisebenen benutzen

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
andilar
User
Beiträge: 19
Registriert: Montag 4. August 2008, 09:25
Wohnort: Braunschweig

Hallo Zusammen,

wenn ich ein Modul habe ähnlich diesem hier:

Code: Alles auswählen

class my_module_library(object):
    def __init__(self):
        print 'my_module_lib'
        
    def another_method(self):
        print 'another method'
dann kann ich das Modul sofern ich in dem gleichen Verzeichnis bin in einem anderen Modul doch so benutzen:

Code: Alles auswählen

import my_module_lib

my_module_lib.my_module_library().another_method()
Ob das nun guter Stil ist oder ähnliches spielt keine Rolle, da ich hier an Vorgaben gebunden bin. Die Syntax des zweiten Teils soll genauso aussehen wie geschrieben.

Jetzt ist es so das ich 2 Etagen tiefer in dem Verzeichnisbaum die selbe Syntax zur Verfügung stellen möchte. Soweit mein python Wissen reicht, kann ich einen import eines selbstgeschrieben Moduls in der Form aber nur durchführen, wenn ich mich im gleichen Verzeichnis befinde. Nun scheint es nicht sehr sinnvoll in alle Verzeichnisse die benötigten Module zu kopieren.

Irgendwo habe ich gesehen das man auch einen Pfad importieren kann. Das ist aber ebenfalls nicht erwünscht, da der Pfad sich entsprechend dem Verzeichnis in dem man das Modul nutzen möchte ändert.

Gibt es eine Möglichkeit für die Laufzeit des Programms ein Modul in den Pythonpfad einzutragen so das es überall per import mein_modul erreichbar ist? Wie macht man das sonst?

Ich bin an python 2.2.1 und winXP gebunden... :cry:

Eine anderer Lösungsansatz wäre auch in Ordnung, danke.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Hey,

innerhalb deiner Anwendung solltest du Module stets über den absoluten Pfad importieren, also etwa

Code: Alles auswählen

from someapplication.core import somemodule

somemodule.SomeClass().some_method()
Damit bist du unabhängig vom Ausführungszeichnis, solange die Applikation selbst sich im Pfad befindet.

Der Pfad lässt sich über die Umgebungsvariable ``PYTHONPATH`` festlegen, zumindest unter Unix. Unter Windows gilt das IIRC allerdings ebenso. Im Code (etwa des Moduls/Scripts, das man zum Starten der Anwendung verwendet) kann man z. B. explizit den übergeordneten Pfad wie folgt eintragen:

Code: Alles auswählen

import sys

sys.path.append('..')
# bzw.
sys.path.insert(0, '..')
An welcher Stelle man den Pfad in die Liste der zu durchsuchenden Pfade einfügt wird bei Überschneidungen von Modul- oder Paketnamen interessant.

Um Überschneidungen durch Modul- oder (Unter-)Paketnamen mit der Standardbibliothek zu vermeiden (etwa ``someapplication.string``) sollte man o. g. absolute Imports benutzen.
andilar hat geschrieben:Irgendwo habe ich gesehen das man auch einen Pfad importieren kann. Das ist aber ebenfalls nicht erwünscht, da der Pfad sich entsprechend dem Verzeichnis in dem man das Modul nutzen möchte ändert.
Kannst du das näher ausführen? Hört sich für mich nicht auf Anhieb nach einer guten Idee an.
andilar
User
Beiträge: 19
Registriert: Montag 4. August 2008, 09:25
Wohnort: Braunschweig

Meun Y0Gi,
Y0Gi hat geschrieben:
andilar hat geschrieben:Irgendwo habe ich gesehen das man auch einen Pfad importieren kann. Das ist aber ebenfalls nicht erwünscht, da der Pfad sich entsprechend dem Verzeichnis in dem man das Modul nutzen möchte ändert.
Kannst du das näher ausführen? Hört sich für mich nicht auf Anhieb nach einer guten Idee an.
Das war die Geschichte mit dem:

Code: Alles auswählen

import sys

sys.path.append('..')
was ich in jedem Modul mit einem anderen angepassten Pfad benutzt hätte und natürlich ekelig aussieht, ohne Frage.

Deinen Ansatz schaue ich mir mal genauer an. Irgendwie habe ich das Gefühl das es für mich noch ein Geheimnis gibt in Richtung python und Anwendungen daraus bauen.
Y0Gi hat geschrieben:innerhalb deiner Anwendung solltest du Module stets über den absoluten Pfad importieren, also etwa

Code: Alles auswählen

from someapplication.core import somemodule

somemodule.SomeClass().some_method() 
Damit bist du unabhängig vom Ausführungszeichnis, solange die Applikation selbst sich im Pfad befindet.

Der Pfad lässt sich über die Umgebungsvariable ``PYTHONPATH`` festlegen, zumindest unter Unix. Unter Windows gilt das IIRC allerdings ebenso. Im Code (etwa des Moduls/Scripts, das man zum Starten der Anwendung verwendet) kann man z. B. explizit den übergeordneten Pfad wie folgt eintragen:

Code: Alles auswählen

import sys

sys.path.append('..')
# bzw.
sys.path.insert(0, '..') 
An welcher Stelle man den Pfad in die Liste der zu durchsuchenden Pfade einfügt wird bei Überschneidungen von Modul- oder Paketnamen interessant.

Um Überschneidungen durch Modul- oder (Unter-)Paketnamen mit der Standardbibliothek zu vermeiden (etwa ``someapplication.string``) sollte man o. g. absolute Imports benutzen.
Dennoch glaube ich das ich in jedem Modul in den Unterverzeichnissen einen anderen Pfad angeben müsste der zu importieren gilt.

Vielleicht noch etwas ausführlicher zu dem Problem:
Es werden von einem angegeben Verzeichnis ausgehend alle Unterverzeichnisse aufgerufen und nach python Modulen durchsucht. Die gefundenen Module sollen anschließend der Reihe nach ausgeführt werden.
Jedes Modul benutzt bei der Ausführung die selben Basismodule mit bestimmten Methoden. Natürlich sollte nicht in jedem Verzeichnis das Basismodul liegen.
Die Anzahl oder die Art der Verschachtelung der Unterverzeichnisse soll auch vollkommen unabhängig von dem obersten Verzeichnis sein.

Vielleicht habe ich da was nicht so richtig verstanden, aber ich möchte die import Anweisung immer gleich lautend haben und nicht je nach Verzeichnisstruktur ändern.
Das ist natürlich irgendwie seltsam, aber eine Anforderung an mein Tool. :/
BlackJack

Die Frage ist halt, wie sehr man Pythons Import-Mechanismus verbiegen muss um Deine Anforderungen zu erfüllen, oder ob man sich das mit den Anforderungen nicht noch einmal überlegen sollte. Du kämpfst hier ein bisschen gegen die Sprache.
andilar
User
Beiträge: 19
Registriert: Montag 4. August 2008, 09:25
Wohnort: Braunschweig

Ja mein Mund ist auch schon ganz fusselig... :wink:
Es sollte aber mit dem sys.path.append('..') und etwas umschreiben der Anforderung doch ganz gut funktionieren.

Vielen Dank
Benutzeravatar
name
User
Beiträge: 254
Registriert: Dienstag 5. September 2006, 16:35
Wohnort: Wien
Kontaktdaten:

Code: Alles auswählen

from __future__ import absolute_import

import ..foo
PEP 328
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
andilar
User
Beiträge: 19
Registriert: Montag 4. August 2008, 09:25
Wohnort: Braunschweig

name hat geschrieben:

Code: Alles auswählen

from __future__ import absolute_import

import ..foo
PEP 328
Ja wie cool, du kannst dir nicht vorstellen wie gerne ich python 2.5 hätte. Das entpricht genau meinem Problem.
Gut zu wissen falls ich nicht mehr an 2.2.1 gebunden bin, danke.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

name hat geschrieben:

Code: Alles auswählen

from __future__ import absolute_import

import ..foo
PEP 328
Erstens ist "import ..foo" ein SyntaxError, zweitens funktioniert "from .. import foo" auch ohne Future-Import, und drittens funktioniert das ganze nur, wenn "foo" im selben Package ist wie das importierende Modul, was die Nützlichkeit der Sache für den OP schon ein wenig einschränkt...
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
lunar

Wenn das so eine Art Plugin-Mechanismus werden soll, dann wäre wohl eher ein Blick auf "imp"-Modul anzuraten anstatt wild sys.path zu verbiegen.
Benutzeravatar
name
User
Beiträge: 254
Registriert: Dienstag 5. September 2006, 16:35
Wohnort: Wien
Kontaktdaten:

birkenfeld hat geschrieben:
name hat geschrieben:

Code: Alles auswählen

from __future__ import absolute_import

import ..foo
PEP 328
Erstens ist "import ..foo" ein SyntaxError, zweitens funktioniert "from .. import foo" auch ohne Future-Import, und drittens funktioniert das ganze nur, wenn "foo" im selben Package ist wie das importierende Modul, was die Nützlichkeit der Sache für den OP schon ein wenig einschränkt...
Hoppla, stimmt. Gestern war nicht so mein Tag, ich sollte mehr schlafen :-)
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
Antworten