Hallo Python-Gemeinde,
ich arbeite mit WinXP und habe zahlreiche Skripte geschrieben, die ich über das Command-Fenster gern aufrufen möchte. Ich schreibe also folgendes:
D:\Jeremy\Skripte> python HelloWorld.py
Wenn HelloWorld.py in meinem aktuellen Verzeichnis liegt, funktioniert es. Wenn ich aber in einem andern Verzeichnis bin, kommt die Fehlermeldung, dass die Datei HelloWorld.py nicht gefunden wurde. Meine PATH-Variable enthält C:\Python26 (sonst würde ja gar nicht klappen) und ich habe PYTHONPATH, der enthält D:\Jeremy\Skripte. Leider kann ich meine Skript nicht systemweit aus einem beliebigen Ordner ausführen. Wo liegt mein Fehler?
Danke und Gruß
Jeremy
Python unter WinXP
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Dein Verstaendnis der Parameter ist falsch. Wenn du den Interpreter so aufrufst, dann erwartet er den _Pfad zu einem Modul_ nicht den Namen; der PYTHONPATH, Suchpfad fuer die Module, bleibt unberuecksichtigt. Dein gewuenschtes Verhalten bekommst du mit
Code: Alles auswählen
python -m HelloWorld
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Nein, das ist nicht Linux-spezifisch. Es handelt sich einfach nur um zwei unterschiedliche Arten, ein Modul auszuführen.
"python foo.py" führt das Modul "foo" unter Angabe des Dateipfades zu diesem Modul aus. Ist der Pfad relativ, muss dementsprechend das Arbeitsverzeichnis stimmen. Mithilfe absoluter Pfade kann man das Modul dagegen von überall heraus ausführen (e.g. "python /pfad/zu/foo.py" oder "python C:\Pfad\zu\foo.py"). Auf diese Weise kann man Module ausführen, die nicht im Import-Pfad enthalten sind. Das betrifft in der Regel Module, die nur als Skripte gedacht sind. Man möchte sich den Import-Pfad ja nicht mit Skripte zumüllen, sondern idealerweise nur Module dort ablegen, die auch wirklich zum Importieren gedacht sind. Außerdem kann man so auch Dateien ausführen, deren Namen keine gültigen Modulnamen sind (wie beispielsweise "python spam-with-eggs.txt").
"python -m foo" dagegen führt das Modul "foo" unter Angabe seines Namens aus. Dieser Name muss erst über eine Suche im Import-Pfad zu einer konkreten Datei aufgelöst werden. Das Modul muss also zum einen im Import-Pfad liegen. Diesen Import-Pfad kannst Du in Python über "sys.path" abfragen und verändern (wobei letzteres meist unterlassen solltest). Zum anderen muss die Datei einen gültigen Modulnamen ab. "python -m spam-with-eggs" funktioniert daher nicht, selbst wenn "spam-with-eggs.txt" im Import-Pfad liegt. Diese Syntax ist dafür gedacht, Module, die sowohl zum Import als auch als Skript gedacht sind, auszuführen.
Nachlesen kannst Du das in Interface options. Dort werden die Argumente und Optionen erklärt, mit welchen man den Interpreter aufrufen kann.
Keinesfalls aber ist diese Syntax dazu gedacht, den Pfad zu Skripten abzukürzen. Du missbrauchst "PYTHONPATH". Füge stattdessen Dein Skriptverzeichnis zu "PATH" hinzu, und ".py" zu "PATHEXT". Dann kannst Du Deine Skripte sogar einfach mit "HelloWorld.py" ausführen.
Grundsätzlich sind alle Python-Dateien technisch auch Module, aber nicht alle lassen sich auch als Module importieren (mittels "import" oder mittels "python -m"). Insbesondere Module, die nur als Skript dienen, sind in der Regel nicht dazu gedacht, importiert zu werden, und sollten daher auch nicht im Import-Pfad liegen.
"python foo.py" führt das Modul "foo" unter Angabe des Dateipfades zu diesem Modul aus. Ist der Pfad relativ, muss dementsprechend das Arbeitsverzeichnis stimmen. Mithilfe absoluter Pfade kann man das Modul dagegen von überall heraus ausführen (e.g. "python /pfad/zu/foo.py" oder "python C:\Pfad\zu\foo.py"). Auf diese Weise kann man Module ausführen, die nicht im Import-Pfad enthalten sind. Das betrifft in der Regel Module, die nur als Skripte gedacht sind. Man möchte sich den Import-Pfad ja nicht mit Skripte zumüllen, sondern idealerweise nur Module dort ablegen, die auch wirklich zum Importieren gedacht sind. Außerdem kann man so auch Dateien ausführen, deren Namen keine gültigen Modulnamen sind (wie beispielsweise "python spam-with-eggs.txt").
"python -m foo" dagegen führt das Modul "foo" unter Angabe seines Namens aus. Dieser Name muss erst über eine Suche im Import-Pfad zu einer konkreten Datei aufgelöst werden. Das Modul muss also zum einen im Import-Pfad liegen. Diesen Import-Pfad kannst Du in Python über "sys.path" abfragen und verändern (wobei letzteres meist unterlassen solltest). Zum anderen muss die Datei einen gültigen Modulnamen ab. "python -m spam-with-eggs" funktioniert daher nicht, selbst wenn "spam-with-eggs.txt" im Import-Pfad liegt. Diese Syntax ist dafür gedacht, Module, die sowohl zum Import als auch als Skript gedacht sind, auszuführen.
Nachlesen kannst Du das in Interface options. Dort werden die Argumente und Optionen erklärt, mit welchen man den Interpreter aufrufen kann.
Keinesfalls aber ist diese Syntax dazu gedacht, den Pfad zu Skripten abzukürzen. Du missbrauchst "PYTHONPATH". Füge stattdessen Dein Skriptverzeichnis zu "PATH" hinzu, und ".py" zu "PATHEXT". Dann kannst Du Deine Skripte sogar einfach mit "HelloWorld.py" ausführen.
Grundsätzlich sind alle Python-Dateien technisch auch Module, aber nicht alle lassen sich auch als Module importieren (mittels "import" oder mittels "python -m"). Insbesondere Module, die nur als Skript dienen, sind in der Regel nicht dazu gedacht, importiert zu werden, und sollten daher auch nicht im Import-Pfad liegen.
Aaah, ok, ich muss mir also überlegen, wofür ich das Skript nutzen möchte.
sys.path wird durch PYTHONPATH geändert.
Das bedeutet, die sauberste Lösung wäre ein Verzeichnis nur für Module (das ich zu PYTHONPATH hinzufüge oder nicht, wenn ich das Standardverzeichnis nehme) und ein Verzeichnis nur für Skripte (zu PATH hinzugefügt). Wenn ich dann ein Modul ausführen möchte, bau ich mir ein Skript, das das gewünschte Modul importiert und die entsprechenden Daten übergibt und andere Daten als Ergbnis bekommt, die dann in eine txt gepeichert werden.
sys.path wird durch PYTHONPATH geändert.
Das bedeutet, die sauberste Lösung wäre ein Verzeichnis nur für Module (das ich zu PYTHONPATH hinzufüge oder nicht, wenn ich das Standardverzeichnis nehme) und ein Verzeichnis nur für Skripte (zu PATH hinzugefügt). Wenn ich dann ein Modul ausführen möchte, bau ich mir ein Skript, das das gewünschte Modul importiert und die entsprechenden Daten übergibt und andere Daten als Ergbnis bekommt, die dann in eine txt gepeichert werden.
@Jeremy: Die sauberste Lösung, sofern diese Bezeichnung passt, wäre IMHO die Module ordentlich zu installieren. Wenn sie zusammen gehören, dann als Package. Und/Oder mit `virtualenv` zu arbeiten, wenn man noch in der Entwicklung steckt oder sie aus anderen Gründen nur beschränkt installieren möchte.
Ich würde jetzt die neuen Module im python\lib Verzeichnis einfügen/erstellen, dann kann ich sie in der Python Shell importieren und in jedem anderen Skript. Ein Skript, das über die Konsole gestartet werden kann, stellt dann die Umgebung (mit Eingabe und Ausgabe zur Verfügung) und importiert das gewünschte Modul und gegebenfalls andere Module.
Oder was verstehst du unter einer ordentlichen Installation?
Oder was verstehst du unter einer ordentlichen Installation?
@Jeremey: Bloß nicht. Es ist nicht ratsam, manuell in der systemweiten Python-Installation herumzudoktorn. Lege für Deine eigenen Module lieber ein Verzeichnis innerhalb Deines Benutzerprofils an, und füge es dem PYTHONPATH hinzu.
Mit einer „ordentlichen Installation“ ist gemeint, dass Du Deine Module mit einer distutils- oder einer distribute-Setuproutine versiehst, und diese verwendest, um Dein Modul geordnet zu installieren, entweder systemweit oder besser mithilfe von virtualenv in einer isolierten Python-Umgebung. So gehen erfahrene Entwickler bei richtigen Python-Projekten vor. Wenn Du vorhast, Python auch (semi-)professionell zu nutzen, also Deine eigenen Module und Programme für andere Leute zu veröffentlichen, ist es empfehlenswert, sich damit zu beschäftigen.
Im Allgemeinen hat BlackJack – wie eigentlich immer – recht, doch ich glaube, dass dieser Aufwand in Deiner Situation übertrieben ist. Wenn Du nur ein paar Skripte schreiben möchtest, welche Dir bei der täglichen Arbeit helfen, aber nicht in größerem Rahmen verteilt werden, dann spricht nichts dagegen, sich einfach ein eigenes Modul-Verzeichnis im PYTHONPATH und ein eigenes Skript-Verzeichnis im PATH zu halten. Für den Anfang ist das vollkommen ausreichend, und sicherlich um Welten einfacher als sich mit den durchaus nicht geringen Untiefen der Python-Paketierung herumzuschlagen.
Mit einer „ordentlichen Installation“ ist gemeint, dass Du Deine Module mit einer distutils- oder einer distribute-Setuproutine versiehst, und diese verwendest, um Dein Modul geordnet zu installieren, entweder systemweit oder besser mithilfe von virtualenv in einer isolierten Python-Umgebung. So gehen erfahrene Entwickler bei richtigen Python-Projekten vor. Wenn Du vorhast, Python auch (semi-)professionell zu nutzen, also Deine eigenen Module und Programme für andere Leute zu veröffentlichen, ist es empfehlenswert, sich damit zu beschäftigen.
Im Allgemeinen hat BlackJack – wie eigentlich immer – recht, doch ich glaube, dass dieser Aufwand in Deiner Situation übertrieben ist. Wenn Du nur ein paar Skripte schreiben möchtest, welche Dir bei der täglichen Arbeit helfen, aber nicht in größerem Rahmen verteilt werden, dann spricht nichts dagegen, sich einfach ein eigenes Modul-Verzeichnis im PYTHONPATH und ein eigenes Skript-Verzeichnis im PATH zu halten. Für den Anfang ist das vollkommen ausreichend, und sicherlich um Welten einfacher als sich mit den durchaus nicht geringen Untiefen der Python-Paketierung herumzuschlagen.
@ lunar: Die Variante mit der Setuproutine klingt sehr interessant. Aber die du sagst, es ist etwas überdemensioniert. Ich werde also die genannte Variante mit den Verzeichnissen in meinem home Bereich anstreben.
Ich bedanke mich für eure Meinungen!
Gruß
Jeremy
Ich bedanke mich für eure Meinungen!
Gruß
Jeremy