Variabler-String (for-Schleife) in os.chdir verwenden

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
martin_
User
Beiträge: 2
Registriert: Montag 5. April 2010, 06:52

Hallo,

ich hab vor ein paar Tagen mit der Python-Programmierung angefangen, und hätte mir gedacht ich stelle ein Bash-Shell-Skript auf Python um, allerdings hab ich dann gewisse Probleme...

irgendwie mag bei mir os.chdir nicht so...


mein Programm sieht ungefähr wie folgt aus,

d.h. ich erzeuge mir dynamisch (per Schleife) bestimmte Strings, die dem Verzeichnisnamen entsprechen, die ich als workverzeichnis verwenden will (will in dem verzeichnis dann extern gewisse Shell-Skripte aufrufen...)



Code: Alles auswählen

#!/usr/bin/python

import os

startwert = 7
endwert = 15

def ausfuehren(startwert,endwert) :
   for k in range(startwert,endwert+1) :
       if k<10 :
          zahlA = ['0',str(k)]
          zahlB = "".join(zahlA)
       else :
          zahlB = str(k)

       #os.chdir(os.path.join(os.getcwd(),

       zeile1A = ["pc",zahlB,"_statistik"]
       zeile1B = "".join(zeile1A)
       zeil3 = os.path.join(os.getcwd(),zeile1B)

       print zeil3
       
       os.chdir(os.path.join(os.getcwd(),zeile1B))
./prg02.py
/home/ruga/pc07_statistik
/home/ruga/pc07_statistik/pc08_statistik

Traceback (most recent call last):
File "/home/martin/prg02.py", line 62, in <module>
ausfuehren(startwert,endwert)
File "/home/martin/prg02.py", line 28, in ausfuehren
os.chdir(os.path.join(os.getcwd(),zeile1B))
OSError: [Errno 2] No such file or directory: '/home/martin/pc07_statistik/pc08_statistik'

Wo liegt hier mein Denkfehler?

Martin
tordmor
User
Beiträge: 100
Registriert: Donnerstag 20. November 2008, 10:29
Wohnort: Stuttgart

os.getcwd liefert das aktuelle Verzeichnis zurück. Nach einem os.chdir ist das natürlich das Verzeichnis in das Du gerade gewechselt bist. Was Du brauchst ist eine Variable in der Du os.getcwd() speicherst bevor Du in die verschiedenen Unterverzeichnisse wechselst.
http://www.felix-benner.com
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

martin_ hat geschrieben:irgendwie mag bei mir os.chdir nicht so...
Dann vermeide doch möglichst dessen Benutzung. Die möglichen Konsequenzen siehst du ja selbst. Du kannst den zusammengesetzten Pfad ja auch aus dem aktuellen Verzeichnis aufrufen, was diese Seiteneffekte vermeiden würde.

Zum Zusammensetzen des Dateinamens könntest du übrigens die String Formatting Syntax nutzen. Ein Beispiel:

Code: Alles auswählen

>>> 'Die Antwort ist: {0}'.format(42)
'Die Antwort ist: 42'
Das ersetzt die geschweifte Klammer (notwendig, damit Python weiß, dass hier etwas interpretiert werden soll) durch den Wert mit dem Index 0, oder anders: mit dem ersten angegebenen Argument, welches in der Funktion `format()` steht. Du kannst bei Zahlen aber auch sagen, dass eine bestimmte Länge angezeigt werden soll, wobei die auf der linken Seite übrigbleibenden Stellen durch eine Ziffer aufgefüllt werden:

Code: Alles auswählen

>>> 'Die Antwort ist: {0:0=5}'.format(42)
'Die Antwort ist: 00042'
Das geht also von fünf Ziffern aus und ersetzt die übriggebliebenen mit einer 0. Analog dazu geht auch:

Code: Alles auswählen

>>> 'Die Antwort ist: {0:9=10}'.format(42)
'Die Antwort ist: 9999999942'
Aber meistens braucht man ja doch eher die Null. Umgemünzt auf dein Vorhaben hätten wir also:

Code: Alles auswählen

>>> 'pc_{0:0=2}statistik'.format(7)
'pc_07statistik'
Und - vorausgesetzt, dass du noch mitkommst... - daraus lässt sich dann eine Funktion machen:

Code: Alles auswählen

>>> statformat = 'pc_{0:0=2}statistik'.format
>>> statformat(7)
'pc_07statistik'
>>> statformat(8)
'pc_08statistik'
>>> statformat(42)
'pc_42statistik'
Wie du siehst, wird die Vorlage mit der Format-Funktion einfach an einen Namen gebunden, aber noch nicht aufgerufen. Das Argument wird daher erst bei Bedarf weitergereicht und du erhälst das passende Ergebnis. Exkurs beendet. ;)
BlackJack

@martin_: Du übertreibst es ein wenig mit dem `join()`. Selbst wenn man nicht wie von snafu vorgeschlagen die `format()`-Methode verwendet, kann man eine kleinere, feste Anzahl von kurzen Zeichenketten auch mit ``+`` konkatenieren. Ich verwende übrigens bei Python 2.x auch weiterhin die Formatierung mittels ``%``-Operator weil es noch viele 2.5er Python-Installationen da draussen gibt. Bei Webhostern, auf "stabilen" Linux-Systemen, in Form von Jython usw.

Du rückst übrigens nur mit drei Leerzeichen pro Ebene ein -- Standard sind vier. Und Konstanten auf Modulebene werden per Konvention komplett in Grossbuchstaben geschrieben.

Das Arbeitsverzeichnis vor einen relativen Pfad zu setzen ist in diesem Fall übrigens überflüssig.

Von `chdir()` würde ich auch dringend abraten. Programme werden dadurch schnell unübersichtlich oder gar unwartbar weil man immer bedenken muss unter welchen Umständen welche Codezeilen in welchem Verzeichnis ausgeführt werden. Das Arbeitsverzeichnis zum Ausführen von externen Programmen kann man auch bei den entsprechenden Aufrufen von `subprocess`-Funktionen erledigen -- da gibt's ein Argument für:

Code: Alles auswählen

#!/usr/bin/env python
import os
from subprocess import call

STARTWERT = 7
ENDWERT = 15

def ausfuehren(startwert, endwert): 
    for i in xrange(startwert, endwert + 1):
        call(['scriptname', 'argument1', 'argument2'],
             cwd='pc%02d_statistik' % i)
martin_
User
Beiträge: 2
Registriert: Montag 5. April 2010, 06:52

Hallo,

danke für die zahlreichen guten Antworten... (muss diese jetzt allerdings erst auf mich wirken lassen (und ausprobieren) ..., verwende Python doch erst seit ein paar Tagen),

dann schau ich auch mal wie ich das "chdir" usw. ablösen, dachte mir beim Lesen des Buches eigentlich, das ich genau das was ich brauche, aber so kann man sich irren ;-)

Vielen Dank

Martin
Antworten