Abschnitt 11 · Lektion 7
Synthese: Der Aufräumer
Der Download-Ordner ist bei den meisten Leuten der unordentlichste Ort auf dem Rechner. Rechnungen,
Fotos, Installationsprogramme, ein Lebenslauf von 2019, alles auf einem Haufen. Das Werkzeug hier
sortiert ihn. Bilder kommen nach Bilder, Dokumente nach Dokumente, Archive nach Archive und
der Rest nach Sonstiges. Alles, was du dafür brauchst, kam in diesem Abschnitt schon einmal vor,
und am Ende hast du ein Werkzeug, das du wirklich benutzen kannst.
Erst aufschreiben, was es tun soll
Wie beim Spritkostenrechner in Lektion 2.7 steht am Anfang ein Plan und noch kein Code.
- Den Ordner durchgehen, nach Namen sortiert, und nur Dateien anfassen. Unterordner bleiben, wie sie sind, auch die, die der Aufräumer beim letzten Mal angelegt hat.
- Für jede Datei den Zielordner aus ihrer Endung bestimmen.
- Den Zielordner anlegen, falls es ihn noch nicht gibt, und die Datei hineinschieben.
- Mitzählen, was wohin gegangen ist, und am Ende eine Zeile dazu ausgeben.
- Das alles nur dann wirklich, wenn man es beim Start ausdrücklich sagt. Sonst wird nur angezeigt, was passieren würde.
Der letzte Punkt ist der wichtigste. Mit ihm geht es los.
Ein Schalter beim Start
import sys
wirklich = "--wirklich" in sys.argv
print(sys.argv)
if wirklich:
print("Jetzt wird verschoben.")
else:
print("Probelauf, es wird nichts verschoben.") Beim Umbenennen hing der Probelauf an einer Variablen im Code. Für ein Werkzeug ist das unpraktisch, weil man für jeden echten Lauf die Datei ändern müsste und hinterher wieder zurück, und das vergisst man.
Besser ist ein Schalter (flag) beim Start, so wie bei den Argumenten der Kommandozeile.
python main.py ist dann der Probelauf, python main.py --wirklich der echte. Die zwei Striche
vorn sind die übliche Form für einen Schalter mit einem ganzen Wort.
Mit "--wirklich" in sys.argv wird gefragt, ob der Schalter irgendwo in der Liste steht. Das ist
sicherer als sys.argv[1] == "--wirklich", weil es ohne Argument keine Position 1 gibt und der
Probelauf dann mit einem IndexError enden würde. Den zweiten Start findest du in der
Befehlsleiste.
Wichtig ist die Richtung. Ohne Schalter passiert nichts, und wenn du ihn vergisst, bekommst du nur
eine Liste zu lesen. Andersherum, mit einem Schalter --probelauf, wäre ausgerechnet das Vergessen
der Fehler, bei dem Dateien verschoben werden.
Nur Dateien
Foto vom Hafen, schon einsortiert Rechnung vom Elektriker Foto vom Strand from pathlib import Path
for eintrag in sorted(Path("downloads").iterdir()):
if not eintrag.is_file():
print("Keine Datei, bleibt liegen:", eintrag.name)
continue
print(eintrag.name, "hat die Endung", eintrag.suffix.lower()) Im Ordner liegt schon ein Unterordner Bilder, vom letzten Aufräumen. Ohne die Frage nach
is_file() hätte er die Endung "" und würde nach Sonstiges geschoben, samt den Fotos darin.
Deshalb wird mit continue alles übersprungen, was keine Datei ist. Die Endung kommt mit lower(),
damit .PDF und .pdf dasselbe sind.
Den Zielordner legt mkdir(exist_ok=True) an. Wenn es ihn schon gibt, wie hier Bilder, ist das
kein Fehler, und die Datei kommt einfach dazu. Ohne exist_ok endet schon der erste Lauf mit einem
FileExistsError, sobald die zweite Datei in denselben Ordner soll.
Zu Hause benutzen
Für deinen echten Download-Ordner ersetzt du Path("downloads") durch Path.home() / "Downloads".
Path.home() ist dein persönlicher Ordner, unter Windows etwa C:\Users\mia, auf dem Mac
/Users/mia. Mehr ändert sich nicht.
Bevor das Werkzeug zum ersten Mal an echte Dateien geht, kopierst du den Ordner und lässt es auf die
Kopie los. Erst als Probelauf. Dann liest du die Liste, startest mit --wirklich und schaust in der
Kopie nach. Ein Programm, das Dateien verschiebt, macht einen Fehler eben bei allen Dateien
zugleich.
Wenn es zuverlässig läuft, kann die Aufgabenplanung es jeden Freitag starten. Dann aber mit
--wirklich als Argument, sonst gibt es jeden Freitag einen Probelauf, den niemand liest.
Foto vom Strand, letzten Sommer Foto vom Hafen Foto vom Strand, diesen Sommer import shutil
from pathlib import Path
for datei in sorted(Path("downloads").glob("*.jpg")):
shutil.move(datei, "downloads/Bilder")
print(datei.name, "liegt jetzt in Bilder") Eine Sache fehlt dem Aufräumer der Aufgabe noch, und die gehört nachgerüstet, bevor er zu Hause von
allein läuft. Wenn im Zielordner schon eine Datei mit demselben Namen liegt, etwa ein strand.jpg
vom letzten Sommer, verweigert shutil.move den Dienst mit
shutil.Error: Destination path 'downloads/Bilder/strand.jpg' already exists.
Der Hafen davor ist dann schon verschoben, alles danach nicht mehr, und der Ordner ist halb
aufgeräumt. Was dagegen hilft, kennst du aus Lektion 11.6. Vorher mit exists() nachsehen und die
Datei mit einer Meldung liegen lassen.
Was die Aufgabe will
Gebaut wird dieses Werkzeug für den Ordner downloads. Ohne Schalter ist es ein Probelauf, mit
--wirklich wird verschoben. In beiden Fällen steht am Ende da, wie viele Dateien in welchen Ordner
gehören.
Zum Mitnehmen
Der Aufräumer geht den Download-Ordner durch und sucht für jede Datei nach ihrer Endung den passenden Unterordner aus. Fehlt der Ordner, wird er angelegt, und dann wird die Datei verschoben. Ohne --wirklich beim Start ist alles nur ein Probelauf, und am Ende steht da, was passieren würde.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.
Was in dieser Lektion steckt
-
Artikel mit 3 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe, dein Code läuft auf einem Server
Öffnet sich mit dem Basis Konto.