Module zur Laufzeit importieren - Problem

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
julianibus
User
Beiträge: 16
Registriert: Montag 21. Juni 2010, 13:04
Wohnort: Aschaffenburg
Kontaktdaten:

Hi,
unter Linux habe ich bis jetzt Module so zur Laufzeit importiert:

Code: Alles auswählen

def __import__(name, globals=None, locals=None, fromlist=None):
	try:
		return sys.modules[name]
	except KeyError:
		pass

	fp, pathname, description = imp.find_module(name)

	try:
		return imp.load_module(name, fp, pathname, description)
	finally:
		if fp:
			fp.close()

Code: Alles auswählen

lev = __import__(os.path.join("levels/scripts/" + level))
miss = lev.mission()
Da hat wunderbar funktioniert. Wenn ich mein Programm unter Windows ausführe kann er das Modul nicht finden. Was stimmt daran nicht und was kann ich tun, damit es auch unter Windows geht?
Danke im Vorraus.
lg julianibus
BlackJack

@julianibus: Wie startest Du denn das Programm unter Linux und unter Windows? Ist das Arbeitsverzeichnis für das Programm relativ gesehen das gleiche?

Du verwendest `os.path.join()` übrigens falsch. *Damit* sollte man Pfade zusammensetzen, und dann auch *alle* Teile, und der Funktion nicht *einen* Pfad übergeben. Dann ist das ziemlich sinnfrei.
julianibus
User
Beiträge: 16
Registriert: Montag 21. Juni 2010, 13:04
Wohnort: Aschaffenburg
Kontaktdaten:

ich wechsle mit beiden Shells in das Verzeichnis, wo das Script, das das Modul einbinden soll, liegt, dann führe ich es unter Linux mit

Code: Alles auswählen

python main.py 
und unter Windows mit

Code: Alles auswählen

C:\python31\python.exe main.py 
aus.

Ich dachte os.path.join ist dazu da die Pfadangaben zu "vereinheitlichen", damit diese plattformunabhängig funktionieren.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

julianibus hat geschrieben:Ich dachte os.path.join ist dazu da die Pfadangaben zu "vereinheitlichen", damit diese plattformunabhängig funktionieren.
Ja. Allerdings indem man die Pfade damit zusammenbaut.

Der genaue Traceback und der inhalt von `sys.path` waere evtl noch hilfreich.
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

cofi hat geschrieben:
julianibus hat geschrieben:Ich dachte os.path.join ist dazu da die Pfadangaben zu "vereinheitlichen", damit diese plattformunabhängig funktionieren.
Ja. Allerdings indem man die Pfade damit zusammenbaut.
Um dich mal an die Hand zu nehmen:

Code: Alles auswählen

os.path.join("levels","scripts",level)
julianibus
User
Beiträge: 16
Registriert: Montag 21. Juni 2010, 13:04
Wohnort: Aschaffenburg
Kontaktdaten:

hi,
also:

Code: Alles auswählen

lev = __import__(os.path.join(os.getcwd(),"levels","scripts",level + ".py"))
In der Fehlermeldung bekomme ich damit den vollständig richtigen Pfad zu meinem Python Modul angezeigt, aber es will nicht funktionieren. auch wenn ich das .py weglasse ändert sich nichts.

Die komplette Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "main.py", line 729, in <module>
    if __name__ == '__main__': main()
  File "main.py", line 266, in main
    checkmission()
  File "main.py", line 537, in checkmission
    lev = __import__(os.path.join(os.getcwd(),"levels","scripts",level + ".py"))

  File "main.py", line 629, in __import__
    fp, pathname, description = imp.find_module(name)
ImportError: No module named C:\Users\julian\Downloads\towerx_0-1\towerx\levels\
scripts\tutorial.py
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Und das funktioniert unter Linux? Das kann ich mir nicht sonderlich vorstellen, weil `imp.find_module` laut Docs mit dem Namen und nicht dem Pfad arbeitet.

Versuch mal

Code: Alles auswählen

def load_level(name):
    LEVEL_PATH = os.path.join(os.getcwd(),"levels","scripts")
    fp, pathname, description = imp.find_module(name, LEVEL_PATH)
    try:
        return imp.load_module(name, fp, pathname, description)
    finally:
        if fp:
           fp.close()
Edit: 2 Anmerkungen:
1. `LEVEL_PATH` sollte man natuerlich besser ausserhalb der Funktion definieren und eventuell `os.getcwd` durch `os.path.abspath(sys.argv[0])` ersetzen, wenn die Level bei dem Programm liegen sollten.
2. Zu benutzen ist es dann so:

Code: Alles auswählen

level = load_level("tutorial")
Antworten