os.walk prüfen ob Ordner vorhanden sind

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
wattwurm
User
Beiträge: 29
Registriert: Sonntag 25. Januar 2015, 17:27
Wohnort: Nordsee

MOin,
dieses mal möchte ich mit os.walk prüfen ob im Arb.-verzeichnis Ordner incl. Unterorder vorhanden sind.
Sind Ordner vorhanden, sollen alle Ordner und Unterordner aufgelistet werden. Dann raus aus os.walk und weiter im Prog.
Sind keine Ordner vorhanden, Ordner estellen und weiter im Prog.

wenn ich das jetzt so mache, haut es auch fast hin:

Code: Alles auswählen

import os
a_pfad = '/home/thomas/script/test/'
for pfad, ordner, datei in os.walk(a_pfad):
        if ordner:
            print('wenn Verz. vorhanden, auflisten und weiter im Prog.') #auch wenn ich die Auflistung nicht brauche
            for o_name in ordner:
                print(o_name)
            break
        else:
            print('Verz. anlegen und weiter im Prog.')

print('***ENDE***')
Das Problem ist das break in if, da wird ja die if-Anweisung abgebrochen und ich bekommen nur den ersten (Obersten) Ordner angezeigt.
Entferne ich das break werden alle Ordner, Unterordner, UNterUnterordner,.... aufgelistet, allerdings wird ja "ordner" irgendwann False und else wird ausgeführt.

was mache ich jetzt wieder falsch? :)
Gruß
wattwurm
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@wattwurm: das Programm macht das, was Du schreibst, wenn Du etwas anderes willst, dann mußt Du das eben so schreiben. In Deinem Fall also einfach kein break und setzen eines Flags.
wattwurm
User
Beiträge: 29
Registriert: Sonntag 25. Januar 2015, 17:27
Wohnort: Nordsee

hallo Sirius3,

ohje, einen Flag setzen? was bedeutet das????

sowas:
ordner = True ?
hwm
User
Beiträge: 39
Registriert: Mittwoch 20. April 2005, 23:33

Probier doch mal

Code: Alles auswählen

continue
an Stelle von

Code: Alles auswählen

break
BlackJack

@hwm: Was soll das denn bringen? Das hätte an der Stelle überhaupt keinen Effekt.
hwm
User
Beiträge: 39
Registriert: Mittwoch 20. April 2005, 23:33

BlackJack hat geschrieben:@hwm: Was soll das denn bringen? Das hätte an der Stelle überhaupt keinen Effekt.
Ich denke doch. Ich habe folgende Ordnerstruktur:

Code: Alles auswählen

testordner
    ordner1
        ordner_in_ordner1
            datei_in_ordner_in_ordner1
        datei_in_ordner1
    ordner2
    datei1
    datei2
Ein Programmlauf sieht dann so aus (mit zusätzlichen prints):

Code: Alles auswählen

>  home ich testordner ['ordner2', 'ordner1'] ['datei1', 'datei2']
wenn Verz. vorhanden, auflisten und weiter im Prog.
ordner2
ordner1
>  home ich testordner ordner2 [] []
 home ich testordner ordner2 Verz. anlegen und weiter im Prog.
>  home ich testordner ordner1 ['ordner_in_ordner1'] ['datei_in_ordner1']
wenn Verz. vorhanden, auflisten und weiter im Prog.
ordner_in_ordner1
>  home ich testordner ordner1 ordner_in_ordner1 [] ['datei_in_ordner_in_ordner1']
 home ich testordner ordner1 ordner_in_ordner1 Verz. anlegen und weiter im Prog.
***ENDE***

Ich denke mal, das ist das, was wattwurm haben möchte.
BlackJack

@hwm: Keine Ahnung was der OP möchte, aber das ``break`` durch ein ``continue`` zu ersetzen macht keinen Sinn weil man dann das ``break`` auch einfach komplett weglassen kann. Ein ``continue`` an der Stelle hätte einfach keinen sichtbaren Effekt, also warum sollte man es dort hinschreiben? Das macht keinen Sinn.
hwm
User
Beiträge: 39
Registriert: Mittwoch 20. April 2005, 23:33

@BlackJack: weil der OP ja sagt:

print('wenn Verz. vorhanden, auflisten und weiter im Prog.') #auch wenn ich die Auflistung nicht brauche

und das verstehe ich so, dass wenn ein Ordner bereits vorhanden ist, der os.walk diesen ignorieren und weiterlaufen soll.

Aber ich geb Dir Recht, die Anfrage des OP ist schon etwas verwirrend.
BlackJack

@hwm: Meine Antwort bezüglich des ``continue`` ist völlig unabhängig davon was eigentlich passieren soll. Die Problemstellung ist dabei völlig irrelevant.

Und wenn ein Ordner von `os.walk()` ignoriert werden soll, dann müsste man ihn aus der entsprechenden Liste entfernen. Sonst nützt auch kein explizites oder implizites ``continue``.
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

wattwurm hat geschrieben:ohje, einen Flag setzen? was bedeutet das???? sowas: ordner = True ?
Hallo wattwurm. Ja, du merkst dir mit einer neuen Variable, dass ein bestimmtes Ereignis aufgetreten ist, vielleicht auch noch weitere Details, lässt aber die Schleife ganz normal weiterlaufen bis zum Ende. Nachdem die Schleife fertig ist, kannst du prüfen, ob dein Flag gesetzt ist, also das Ereignis aufgetreten ist, und dann entsprechend darauf reagieren. Ich würde vielleicht nicht die Variable "ordner" nehmen, denn die gibt es ja schon, sondern eine neue.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

wattwurm hat geschrieben:Das Problem ist das break in if, da wird ja die if-Anweisung abgebrochen und ich bekommen nur den ersten (Obersten) Ordner angezeigt.
Es wird nicht die `if`-Anweisung abgebrochen, sondern die Schleife. `break` bricht immer die komplette Schleife ab. `continue` bricht den aktuellen Schleifendurchlauf ab.

Beide sind jedoch mit Vorsicht zu genießen, da deren Einsatz schnell zu Missverständnissen oder umständlichem Code führen kann. Es ist oftmals besser, mittels `if`-Anweisung zu sagen, was in bestimmten Fällen getan werden soll. Wenn der Fall nicht auftritt, dann wird der "if-Block" halt übersprungen. Selbst wenn dann gar nichts anderes mit dem Element passieren soll, ist dieser Weg IMHO einfacher nachzuvollziehen als ein frühes `continue`.

In Fällen, wo ein frühzeitiges Abbrechen sinnvoll ist (etwa bei einer sequentiellen Suche), würde ich eher mit einer Hilfsfunktion arbeiten, die im Erfolgsfall mit `return` aus der Schleife "heraus springt". So wird das `break` dann auch vermieden und man kann trotzdem noch etwas mit dem Ergebnis anstellen. Ein typisches Szenario wäre eine äußere Schleife, die ihre innere Schleife in eine solche Hilfsfunktion auslagert.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@hwm: Bei dem im Eingangsbeitrag gezeigten Code besteht der Rumpf der Schleife lediglich aus einer if-else-Verzweigung. Ein `continue` am Ende des if-Zweiges hat so oder so nichts mehr vor sich, was es noch überspringen könnte. Also ist die Anweisung dort überflüssig. Ich denke, darauf wollte BlackJack hinaus.
hwm
User
Beiträge: 39
Registriert: Mittwoch 20. April 2005, 23:33

snafu hat geschrieben:@hwm: Bei dem im Eingangsbeitrag gezeigten Code besteht der Rumpf der Schleife lediglich aus einer if-else-Verzweigung. Ein `continue` am Ende des if-Zweiges hat so oder so nichts mehr vor sich, was es noch überspringen könnte. Also ist die Anweisung dort überflüssig. Ich denke, darauf wollte BlackJack hinaus.
Stimmt!
wattwurm
User
Beiträge: 29
Registriert: Sonntag 25. Januar 2015, 17:27
Wohnort: Nordsee

Hallo
Habe es nun so hinbekommen:

Code: Alles auswählen

# -*- coding: utf-8 -*-
import os
a_pfad = '/home/thomas/script/test/'
#v_name = 'verz name/unter verz name 1/unter verz name 2/unter verz name 3/unter verz 4'
v1_name = 'neuer Ordner'
verzeichnisse = []
for pfad, ordner, datei in os.walk(a_pfad):
        for o_name in ordner:
                verzeichnisse.append(os.path.join(pfad,o_name))
if verzeichnisse:
        for ausgabe in verzeichnisse:
                print(ausgabe)
else:
        print('Verz. anlegen')
        for i in range(1,11):
                os.mkdir(os.path.join(a_pfad,v1_name+' '+str(i)))
                
print(bool(verzeichnisse))        
print('***ENDE***')
Ob's gut ist weiß ich net, aber es läuft so wie ich mir gedacht habe :D

@Kebap, ist das in etwa so wie du es gemeint hast?

@snafu,da muß ich drüber nachdenken :? :K
hast Du evtl. ein kleines Beispiel?

edit:
Ist das 'os.path.join' in
os.mkdir(os.path.join(a_pfad,v1_name+' '+str(i)))
überhaupt nötig?
Man könnte ja auch

Code: Alles auswählen

os.mkdir(a_pfad,v1_name+' '+str(i))
machen, dass funzt ja auch
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Generell eine kleine Anmerkung: Benutze keine Tabulatoren zum Einrücken, sondern *vier* Spaces. (Man kann jeden guten Editor so einstellen, dass er statt eines Tabs vier Leerzeichen druckt)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@wattwurm: wenn Du glaubst, dass

Code: Alles auswählen

os.mkdir(a_pfad,v1_name+' '+str(i))
funzt, dann probier's doch.
Generell sollte man statt Stringzusammenstückelung mit + lieber .format benutzen. (Und Leerzeichen in Dateinamen nerve, ..., irgendwann)
BlackJack

@wattwurm: `verzeichnisse` wird ja gar nicht wirklich verwendet und dafür wofür es verwendet wird ist `os.walk()` der komplette Overkill. Du gehst da komplette, potentiell tiefe Verzeichnishierarchien durch und merkst Dir alle kompletten Pfade in den selbigen, nur um einen Test zu implementieren ob im *obersten* Verzeichnis mindestens *ein* Unterverzeichnis existiert. So einen Test hätte man mit `any()`, `os.path.isdir()`, `os.path.join()`, und `os.listdir()` als kompakten Ausdruck definieren können. Oder mit dem `pathlib`-Modul.
wattwurm
User
Beiträge: 29
Registriert: Sonntag 25. Januar 2015, 17:27
Wohnort: Nordsee

wenn Du glaubst, dass

os.mkdir(a_pfad,v1_name+' '+str(i))

funzt, dann probier's doch.
Ok, so nicht.

Aber so:
os.mkdir(a_pfad+v1_name+' '+str(i))
funktionuckelt es.
(Und Leerzeichen in Dateinamen nerve, ..., irgendwann)
Stimmt!
Die will ich aber haben, um sie dann hiermit:http://www.python-forum.de/viewtopic.ph ... 89#p271889 zu eliminieren

`verzeichnisse` wird ja gar nicht wirklich verwendet und dafür wofür es verwendet wird ist `os.walk()` der komplette Overkill. Du gehst da komplette, potentiell tiefe Verzeichnishierarchien durch und merkst Dir alle kompletten Pfade in den selbigen, nur um einen Test zu implementieren
Ja, dass leuchtet mir ein.

Code: Alles auswählen

# -*- coding: utf-8 -*-
import os
a_pfad = '/home/thomas/script/test/'
#v_name = 'verz name/unter verz name 1/unter verz name 2/unter verz name 3/unter verz 4'
v1_name = 'neuer Ordner'

def auflisten():
    print('in Funktion')
    
    for pfad, ordner, datei in os.walk(a_pfad):
        for name in ordner:
            print(name)
    return None
        
vorh = bool(os.listdir(a_pfad))
if vorh:
    inhalt = auflisten()
    
else:
    for i in range(1, 11):
        ##os.mkdir(os.path.join(a_pfad,v1_name+' '+str(i)))
        os.mkdir(os.path.join(a_pfad,'{0} {1}'.format(v1_name,str(i))))         
    print('Verzeichnisse angelegt!')
        
print(vorh)
print('***ENDE***')
Ist das jetzt ein bischen besser? :K

Schönen Sonntag noch :)
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@wattwurm: eine Funktion die nichts zurückgibt, gibt automatisch None zurück, das return in "auflisten" ist also unnötig. Wenn Du vorh nicht mehr brauchst, kannst Du gleich "if os.listdir(a_pfad):" schreiben. "inhalt" wird nirgends benutzt und ist sowieso immer None. Das str in format ist unnötig, da format sowieso dafür sorgt, dass es einen String gibt.
wattwurm
User
Beiträge: 29
Registriert: Sonntag 25. Januar 2015, 17:27
Wohnort: Nordsee

Danke Sirius3!

Dann sieht es jetzt so aus:

Code: Alles auswählen

# -*- coding: utf-8 -*-
import os
a_pfad = '/home/thomas/script/test/'
#v_name = 'verz name/unter verz name 1/unter verz name 2/unter verz name 3/'
v1_name = 'neuer Ordner'


def auflisten():
    for pfad, ordner, datei in os.walk(a_pfad):
        for o_name in ordner:
            print('Ordner:', os.path.join(pfad, o_name))
        for d_name in datei:
            print('Dateien:', os.path.join(pfad, d_name))
if os.listdir(a_pfad):
    auflisten()
else:
    for i in range(1, 11):
        os.mkdir(os.path.join(a_pfad, '{0} {1}'.format(v1_name, i)))
        print('Verzeichnisse angelegt!')
print('***ENDE***')
Und die Ausgabe so:
Ordner: /home/thomas/script/test/neuer Ordner 10
Ordner: /home/thomas/script/test/neuer Ordner 6
Ordner: /home/thomas/script/test/neuer Ordner 9
Ordner: /home/thomas/script/test/neuer Ordner 4
Ordner: /home/thomas/script/test/neuer Ordner 5
Ordner: /home/thomas/script/test/neuer Ordner 3
Ordner: /home/thomas/script/test/neuer Ordner 8
Ordner: /home/thomas/script/test/neuer Ordner 7
Ordner: /home/thomas/script/test/neuer Ordner 2
Ordner: /home/thomas/script/test/neuer Ordner 1
Dateien: /home/thomas/script/test/Textdatei
Dateien: /home/thomas/script/test/neuer Ordner 10/Textdatei
Ordner: /home/thomas/script/test/neuer Ordner 5/Neuer Ordner
Dateien: /home/thomas/script/test/neuer Ordner 5/Textdatei
Dateien: /home/thomas/script/test/neuer Ordner 5/Neuer Ordner/HTML-Datei
Dateien: /home/thomas/script/test/neuer Ordner 5/Neuer Ordner/Textdatei
Dateien: /home/thomas/script/test/neuer Ordner 5/Neuer Ordner/HTML-Datei 1
Ordner: /home/thomas/script/test/neuer Ordner 7/Neuer Ordner
Ordner: /home/thomas/script/test/neuer Ordner 7/Neuer Ordner 2
Ordner: /home/thomas/script/test/neuer Ordner 7/Neuer Ordner 1
Ordner: /home/thomas/script/test/neuer Ordner 1/Neuer Ordner
Ordner: /home/thomas/script/test/neuer Ordner 1/Neuer Ordner 1
***ENDE***
Jetzt würde ich noch gerne in den Ordnern "test/neuer Ordner 1 - 10" weitere Unterordner und Dateien erstellen wie geht man das an?
Müsste ich aus der for Schleife in "auflisten()":

Code: Alles auswählen

for o_name in ordner:
            print('Ordner:', os.path.join(pfad, o_name))
wieder eine Liste machen (wäre das nicht doppelt gemoppelt? 'ordner und 'datei' sind ja listen') mit 'isdir', 'isfile' prüfen ob was vorhanden ist, wenn nicht, was erstellen?
Antworten