Python Grundkurs Teil 010: Zwei Ordner vergleichen und fehlende Dateien finden
Worum geht es in diesem Teil?
Welche Dateien fehlen im anderen Ordner? In diesem Teil vergleichen wir die Dateinamen aus zwei Ordnern in beide Richtungen. Ihr entscheidet dabei, ob die Dateiendung berücksichtigt wird oder ob nur der Name vor der letzten Endung zählt. Das ist beispielsweise praktisch, wenn ihr Originalbilder mit exportierten Bildern oder Word-Dokumente mit PDF-Dateien abgleichen möchtet.
Wir erstellen wieder zwei Varianten: einen Vergleich mit fest eingetragenen Ordnern und eine SendTo-Version für zwei im Windows-Explorer ausgewählte Ordner. Die Ergebnisse erscheinen im Fenster und werden im Echtmodus zusätzlich als Textdateien gespeichert.
Was ist das Ziel?
Ihr erhaltet zwei Listen: Namen aus Ordner 2, die in Ordner 1 fehlen, und Namen aus Ordner 1, die in Ordner 2 fehlen. Vorhandene Projektdateien werden dabei weder umbenannt noch kopiert, verschoben oder gelöscht.
Ein Namensvergleich ist kein Inhaltsvergleich.
Gleiche Namen bedeuten nicht, dass Dateien denselben Inhalt besitzen. Das Skript prüft weder Dateigrößen noch Änderungszeiten oder Prüfsummen. Unterordner werden nicht durchsucht und fehlende Ordner werden nicht ermittelt.
Warum verwenden wir diesmal mehrere Funktionen?
Zum Abschluss des Grundkurses organisieren wir einzelne Aufgaben in Funktionen. Dadurch bekommt jede Aufgabe einen eigenen Namen: Dateien einlesen, Vergleichsnamen sammeln, Berichte erstellen und Berichte speichern. Wiederkehrende Abläufe müssen wir so innerhalb eines Skripts nur einmal schreiben.
Bei kleinen Skripten können Anweisungen direkt untereinander stehen. Wenn ein Programm wächst, helfen Funktionen dabei, Aufgaben zu überblicken und mehrfach zu verwenden. Python unterstützt außerdem Klassen, mit denen sich zusammengehörige Daten und Methoden organisieren lassen. Für diesen Ordnervergleich reichen normale Funktionen gut aus.
Wir erklären den Code in der Reihenfolge, in der er gebraucht wird. Wir beginnen beim Startblock und gehen zu main(). Sobald dort eine Funktion aufgerufen wird, schauen wir uns deren Aufgabe an und kehren anschließend an die Aufrufstelle zurück.
Hinweis zur Kursreihe
Dieses Tutorial gehört zum Python-Grundkurs und setzt dieselbe Aufgabe wie die entsprechenden Batch- und PowerShell-7-Varianten um. Ihr könnt die verschiedenen Schreibweisen direkt vergleichen. Python verwendet hier nur seine Standardbibliothek; für die Zwischenablage wird das in Windows enthaltene clip.exe aufgerufen.
Downloads zu diesem Teil
Dateien für Python Grundkurs Teil 010:
Download Python_Grundkurs_010_Fehlende_Dateien_vergleichen.zip
Enthalten sind zwei Python-Skripte, je zwei Starter-Batchdateien und kurze Testhinweise. Die vollständigen Skripte findet ihr auch weiter unten zum Kopieren.
Entpacken nach:
C:\TOPTORIALS_CODE\020_Python_Grundkurs
Testumgebung zum Mitmachen
Testumgebung für Windows-Automatisierung:
Download TOPTORIALS_Testdaten_Windows_Automatisierung_V001.zip
Entpacken nach:
C:\TOPTORIALS_CODE\1000_TESTBEREICH
Verwendet die Vergleichsordner aus Teil 010. Kontrolliert nach dem Entpacken die tatsächlichen Verzeichnisnamen und passt die vorbereiteten Pfade im Python-Skript bei Bedarf an. Die Vergleichsordner werden vom Skript nicht selbst erstellt.
Die feste Variante ist auf diese beiden Pfade vorbereitet:
C:\TOPTORIALS_CODE\1000_TESTBEREICH\TOPTORIALS_Testdaten_Windows_Automatisierung_Python_V001\010_Fehlende_Dateien_vergleichen\01_Feste_Ordner_vergleichen\01_Ordner_1
C:\TOPTORIALS_CODE\1000_TESTBEREICH\TOPTORIALS_Testdaten_Windows_Automatisierung_Python_V001\010_Fehlende_Dateien_vergleichen\01_Feste_Ordner_vergleichen\02_Ordner_2
Alternativ könnt ihr zwei eigene Testordner anlegen oder die vorhandenen PowerShell-Testordner verwenden. Tragt dafür die entsprechenden Pfade in ORDNER1 und ORDNER2 ein.
Sicherheitshinweis
Beginnt mit Kopien unwichtiger Dateien und kontrolliert die angezeigten Ordnerpfade. Der Testmodus erstellt keine Ergebnisdateien. Bei SendTo wird jedoch auch im Testmodus der vorherige Inhalt der Zwischenablage durch die Berichte ersetzt.
Ihr wisst ja, die Nutzung dieses Codes erfolgt natürlich wieder auf eigene Verantwortung. Ich übernehme keine Haftung für Datenverluste, unbeabsichtigte Änderungen oder andere Schäden, die durch die Verwendung des Skripts entstehen könnten.
Voraussetzungen
- Windows mit Python 3 und dem Python-Launcher
py. - Leserechte für beide Vergleichsordner.
- Im Echtmodus Schreibrechte im Skriptordner beziehungsweise in beiden SendTo-Ordnern.
- Python-Datei und zugehörige Starterdateien liegen nebeneinander.
- Es müssen keine zusätzlichen Python-Pakete installiert werden.
Wenn auf eurem Rechner nur der Befehl python verfügbar ist, ersetzt in den Startern py -3 durch python. Die Option -X utf8 bleibt erhalten.
Die beiden Varianten im Überblick
| Variante | Vergleichsordner | Ergebnis im Echtmodus |
|---|---|---|
| Feste Ordner | Direkt im Python-Skript eingetragen | Ein gemeinsamer Bericht neben der Python-Datei |
| SendTo | Genau zwei übergebene Ordner | Ein eigener Bericht in jedem Ordner; beide Berichte zusätzlich in der Zwischenablage |
C:\TOPTORIALS_CODE\020_Python_Grundkurs\010_Fehlende_Dateien_vergleichen\01_Feste_Ordner_vergleichen
010_fehlende_dateien_vergleichen.py
010_fehlende_dateien_vergleichen_starter_batch_test.bat
010_fehlende_dateien_vergleichen_starter_batch.bat
C:\TOPTORIALS_CODE\020_Python_Grundkurs\010_Fehlende_Dateien_vergleichen\02_SendTo_Zwei_Ordner_vergleichen
010_sendto_zwei_ordner_vergleichen.py
010_sendto_zwei_ordner_vergleichen_starter_batch_test.bat
010_sendto_zwei_ordner_vergleichen_starter_batch.bat
Die beiden Starter einer Variante haben denselben Inhalt. Der tatsächliche Dateiname entscheidet über den Modus. Ihr könnt den Teststarter kopieren und bei der Kopie _test aus dem Namen entfernen.
Vergleich mit oder ohne Dateiendung
| Ordner 1 | Ordner 2 | JA: mit Endung | NEIN: ohne Endung |
|---|---|---|---|
| Bild_001.CR3 | Bild_001.jpg | Jeweils anderer Name | Gemeinsamer Name Bild_001 |
| Bericht.docx | Bericht.pdf | Jeweils anderer Name | Gemeinsamer Name Bericht |
| Notiz.txt | notiz.TXT | Gleicher Vergleichsname | Gleicher Vergleichsname |
| Bild_002.jpg | Kein entsprechender Name | Bild_002.jpg fehlt in Ordner 2 | Bild_002 fehlt in Ordner 2 |
JA verwendet Path.name, also den vollständigen Dateinamen. NEIN verwendet Path.stem, also den Namen ohne letzte Dateiendung. Aus Bericht.final.pdf wird beispielsweise Bericht.final. Normale Dateien ohne Endung bleiben mit ihrem Namen im Vergleich.
Vergleichsschlüssel werden mit casefold() vorbereitet. Dadurch wird Groß-/Kleinschreibung beim Vergleich ignoriert. Bei manchen Unicode-Sonderfällen arbeitet das anders als der PowerShell-Vergleich; für die hier verwendeten Kursbeispiele sind die Ergebnisse gleich.
Testmodus und Echtmodus
| Verhalten | Mit _test | Ohne _test |
|---|---|---|
| Vergleichen und Ergebnisse anzeigen | Ja | Ja |
| Berichte speichern | Nein | Ja |
| SendTo-Zwischenablage aktualisieren | Ja | Ja |
| Projektdateien umbenennen, verschieben oder löschen | Nein | Nein |
Die Frage nach JA oder NEIN betrifft ausschließlich die Dateiendung. Sie ist keine zusätzliche Sicherheitsbestätigung. Ohne _test werden die Ergebnisdateien direkt nach dem Vergleich gespeichert.
Direkt zu den Abschnitten
- Normale Variante ausprobieren
- Vollständiges Python-Skript
- Python entlang des Programmablaufs erklärt
- List Comprehensions ausführlich erklärt
- Starter-Batchdatei erklärt
- SendTo einrichten und ausprobieren
- SendTo-Skript und zusätzliche Funktionen
- Argumente und Parameter der Berichtsfunktion
1. Die normale Variante ausprobieren
- Öffnet
010_fehlende_dateien_vergleichen.pyund kontrolliertTESTBEREICH,ORDNER1undORDNER2. - Startet die Batchdatei mit
_testim Namen. Im Fenster erscheintTestmodus: JA. - Gebt
JAein, um vollständige Dateinamen zu vergleichen. - Startet erneut und gebt
NEINein, um die letzte Dateiendung zu ignorieren. - Startet anschließend die Batchdatei ohne
_test. Zusätzlich zur Anzeige entsteht nun ein Bericht im Ordner der Python-Datei.
vergleich_ergebnis_2026-09-16_14-30-00.txt
Die normale Variante speichert beide Vergleichsrichtungen gemeinsam in dieser Datei. Der Ablageort hängt vom Python-Skript ab und nicht davon, aus welchem Arbeitsverzeichnis ihr es gestartet habt.
Vollständiges Python-Skript: feste Ordner
# ============================================================
# TOPTORIALS OFFICE - Python Grundkurs Teil 010
# Script: 010_fehlende_dateien_vergleichen.py
# Beschreibung:
# Vergleicht zwei fest eingetragene Ordner.
# Vergleich anhand der Dateinamen, wahlweise ohne letzte Endung.
# Groß-/Kleinschreibung wird ignoriert. Kein Inhaltsvergleich.
# Nur direkt enthaltene Dateien, einschließlich versteckter Dateien.
# Unterordner werden nicht durchsucht.
#
# Autor: Chris
# YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
# Webseite: https://www.toptorials.com
# Version: Grundkurs 1.0
# Stand: 2026-09-16
#
# Hinweise:
# Mit _test im Starternamen wird --test übergeben:
# Ergebnis anzeigen, aber keine Ergebnisdateien erstellen.
# Ohne _test werden zusätzlich Berichte mit Zeitstempel gespeichert.
# Bestehende gleichnamige Berichte werden nicht überschrieben.
# Der Ergebnisbericht wird im Ordner dieses Skripts gespeichert.
# Zuerst mit Testdaten arbeiten. Nutzung auf eigene Verantwortung.
# ============================================================
from datetime import datetime
from pathlib import Path
import sys
# Diese beiden Ordner können an die eigene Umgebung angepasst werden.
TESTBEREICH = Path(r"C:\TOPTORIALS_CODE\1000_TESTBEREICH\TOPTORIALS_Testdaten_Windows_Automatisierung_Python_V001")
ORDNER1 = TESTBEREICH / "010_Fehlende_Dateien_vergleichen/01_Feste_Ordner_vergleichen/01_Ordner_1"
ORDNER2 = TESTBEREICH / "010_Fehlende_Dateien_vergleichen/01_Feste_Ordner_vergleichen/02_Ordner_2"
def dateien_einlesen(ordner, berichte_ausschliessen=False):
dateien = []
for datei in ordner.iterdir():
if not datei.is_file():
continue
name = datei.name.casefold()
if berichte_ausschliessen and name.startswith("vergleich_fehlt_hier_") and name.endswith(".txt"):
continue
dateien.append(datei)
return sorted(dateien, key=lambda datei: datei.name.casefold())
def namen_sammeln(dateien, mit_endung):
# Der Vergleichsschlüssel ignoriert Groß- und Kleinschreibung.
# Als Wert bleibt die ursprüngliche Schreibweise erhalten.
namen = {}
for datei in dateien:
name = datei.name if mit_endung else datei.stem
namen.setdefault(name.casefold(), name)
return namen
def bericht_speichern(pfad, zeilen):
# "x" erstellt eine neue Datei und verhindert das Überschreiben.
with pfad.open("x", encoding="utf-8") as datei:
datei.write("\n".join(zeilen) + "\n")
def main():
try:
argumente = sys.argv[1:]
if argumente not in ([], ["--test"]):
raise ValueError("Erlaubt ist nur der optionale Schalter --test.")
test = "--test" in argumente
ordner1, ordner2 = ORDNER1, ORDNER2
for ordner in (ordner1, ordner2):
if not ordner.is_dir():
raise ValueError(f"Ordner nicht gefunden: {ordner}")
print(f"\nTestmodus: {'JA' if test else 'NEIN'}\n")
print(f"Ordner 1: {ordner1}")
print(f"Ordner 2: {ordner2}\n")
print("JA = vollständigen Dateinamen vergleichen")
print("NEIN = Dateiendung ignorieren\n")
eingabe = input("Dateiendung berücksichtigen? JA/NEIN: ").strip().upper()
if eingabe not in ("JA", "NEIN"):
raise ValueError("Bitte JA oder NEIN eingeben.")
mit_endung = eingabe == "JA"
dateien1 = dateien_einlesen(ordner1)
dateien2 = dateien_einlesen(ordner2)
namen1 = namen_sammeln(dateien1, mit_endung)
namen2 = namen_sammeln(dateien2, mit_endung)
fehlt1 = [name for schluessel, name in namen2.items() if schluessel not in namen1]
fehlt2 = [name for schluessel, name in namen1.items() if schluessel not in namen2]
bericht = [
"Vergleichsergebnis", "",
f"Ordner 1: {ordner1}", f"Ordner 2: {ordner2}",
f"Dateiendung berücksichtigen: {eingabe}", "",
"Dateien aus Ordner 2, die in Ordner 1 fehlen:",
*fehlt1, "",
"Dateien aus Ordner 1, die in Ordner 2 fehlen:",
*fehlt2, "", "Zusammenfassung:",
f"Dateien in Ordner 1: {len(dateien1)}",
f"Dateien in Ordner 2: {len(dateien2)}",
f"Fehlende Namen in Ordner 1: {len(fehlt1)}",
f"Fehlende Namen in Ordner 2: {len(fehlt2)}",
]
print("\n" + "\n".join(bericht) + "\n")
if test:
print("Testmodus: Es wurde keine Ergebnisdatei erstellt.")
else:
zeitstempel = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
ausgabe = Path(__file__).resolve().parent / f"vergleich_ergebnis_{zeitstempel}.txt"
bericht_speichern(ausgabe, bericht)
print(f"Ergebnisdatei erstellt: {ausgabe}")
return 0
except (OSError, ValueError, EOFError) as fehler:
print(f"\nFehler: {fehler}")
return 1
if __name__ == "__main__":
sys.exit(main())
2. Den Python-Code entlang seines Ablaufs verstehen
Der Startblock am Ende der Datei
if __name__ == "__main__":
sys.exit(main())
Python verarbeitet die Datei zunächst von oben nach unten: Es lädt die importierten Module, setzt die vorbereiteten Ordnerpfade und führt die Funktionsdefinitionen aus. Dabei werden die Funktionen angelegt; ihre Funktionskörper laufen noch nicht. Unser eigentlicher Vergleich startet erst mit dem Aufruf von main().
Wird die Datei direkt gestartet, erhält die besondere Variable __name__ den Wert "__main__". Die Bedingung ist dann erfüllt. Wird die Datei stattdessen als Modul importiert, enthält __name__ den Modulnamen und dieser Startblock wird übersprungen. Die definierten Funktionen können so von einem anderen Skript verwendet werden, ohne automatisch den Vergleich zu starten.
main ist kein vorgeschriebener Funktionsname, sondern eine verbreitete Konvention für die Hauptfunktion. Zuerst läuft main() vollständig. Ihr Rückgabewert wird danach an sys.exit() übergeben. Bei uns bedeutet 0 Erfolg und 1 einen behandelten Fehler. Die Starter-Batchdatei kann diesen Status übernehmen.
Module und vorbereitete Ordnerpfade
datetime liefert Datum und Uhrzeit, Path verarbeitet Dateisystempfade und sys stellt unter anderem die Programmargumente und exit() bereit. Die großgeschriebenen Namen für die vorbereiteten Pfade sind eine Konvention für feste Einstellungen; Python verbietet ihre spätere Änderung dadurch nicht.
ORDNER1 = Path(r"C:\Test\Ordner_1")
ORDNER2 = Path(r"C:\Test\Ordner_2")
So könnt ihr alternativ vollständige eigene Pfade eintragen. Das vorangestellte r verhindert bei diesem String, dass Python Backslashes bereits als Teil eigener Escape-Sequenzen verarbeitet. Path erzeugt daraus ein Pfadobjekt. Mit / können wir bei einem solchen Objekt weitere Pfadbestandteile anhängen; hier ist das keine Division.
In main(): Argumente und Ordner prüfen
argumente = sys.argv[1:]
if argumente not in ([], ["--test"]):
raise ValueError("Erlaubt ist nur der optionale Schalter --test.")
test = "--test" in argumente
sys.argv enthält den Skriptaufruf und die übergebenen Argumente. Mit [1:] übernehmen wir die Einträge ab Position 1; der Eintrag an Position 0 bezeichnet das gestartete Skript. Die normale Variante akzeptiert eine leere Argumentliste oder genau ["--test"]. Andere Angaben lösen mit raise einen Fehler aus.
ordner1, ordner2 = ORDNER1, ORDNER2
for ordner in (ordner1, ordner2):
if not ordner.is_dir():
raise ValueError(f"Ordner nicht gefunden: {ordner}")
Die beiden vorbereiteten Pfade werden den lokalen Variablen zugewiesen. Die Schleife geht das Tupel (ordner1, ordner2) nacheinander durch. In ordner steht jeweils der aktuell geprüfte Pfad. is_dir() prüft, ob es sich um einen vorhandenen Ordner handelt.
Eingabe und f-Strings
print(f"\nTestmodus: {'JA' if test else 'NEIN'}\n")
Das f vor dem String erlaubt Ausdrücke in geschweiften Klammern. Der bedingte Ausdruck liefert JA, wenn test wahr ist, andernfalls NEIN. steht in diesem normalen String für einen Zeilenumbruch.
eingabe = input("Dateiendung berücksichtigen? JA/NEIN: ").strip().upper()
mit_endung = eingabe == "JA"
input() nimmt die Eingabe entgegen. strip() entfernt Leerraum am Anfang und Ende, upper() wandelt den Text in Großbuchstaben um. Damit werden auch ja und nein akzeptiert. Die Prüfung dazwischen erlaubt nur JA oder NEIN. Der Vergleich eingabe == "JA" ergibt den Wahrheitswert True oder False, der in mit_endung gespeichert wird.
Beim ersten Funktionsaufruf: dateien_einlesen()
dateien1 = dateien_einlesen(ordner1)
dateien2 = dateien_einlesen(ordner2)
Wir übergeben einen Ordner an die Funktion. Dort durchläuft ordner.iterdir() die direkt enthaltenen Elemente. is_file() begrenzt die Auswahl auf Dateien. continue überspringt den restlichen aktuellen Schleifendurchlauf. Mit append() werden passende Pfadobjekte zur Liste hinzugefügt.
return sorted(dateien, key=lambda datei: datei.name.casefold())
sorted() liefert eine sortierte Liste. Über key geben wir an, welcher Wert für die Sortierung verwendet wird. lambda definiert dafür eine kleine namenlose Funktion: Sie erhält ein Dateiobjekt und liefert dessen mit casefold() vorbereiteten Namen. Sortiert werden die Pfadobjekte nach diesen Namen; die Dateinamen selbst werden nicht verändert. return gibt die fertige Liste an die Aufrufstelle zurück.
Warum steht in der Definition berichte_ausschliessen=False?
def dateien_einlesen(ordner, berichte_ausschliessen=False):
Die Funktion besitzt zwei Parameter. ordner hat keinen Standardwert und muss deshalb angegeben werden. Für berichte_ausschliessen ist False als Standardwert festgelegt. Wird kein zweites Argument übergeben, verwendet die Funktion automatisch diesen Wert. Der Ausschluss von Berichtsnamen ist dann deaktiviert.
dateien_einlesen(ordner1)
dateien_einlesen(ordner1, False)
dateien_einlesen(ordner1, berichte_ausschliessen=False)
Diese drei Aufrufe wählen dieselbe Einstellung. Ein ausdrücklich übergebener Wert ersetzt den Standardwert für den jeweiligen Aufruf. Bei SendTo verwenden wir später deshalb:
dateien_einlesen(ordner1, berichte_ausschliessen=True)
Hier wird der zweite Parameter benannt, damit seine Bedeutung schon beim Lesen des Aufrufs deutlich ist. Ohne =False wäre dieser Parameter in unserer Definition ebenfalls verpflichtend:
def dateien_einlesen(ordner, berichte_ausschliessen):
...
# Bei dieser Definition fehlt ein erforderliches Argument:
dateien_einlesen(ordner1) # TypeError
Merksatz:
=False legt den Standardwert fest. Wird das zweite Argument weggelassen, verwendet Python automatisch False. Ein ausdrücklich übergebener Wert ersetzt den Standardwert für diesen Aufruf.
Vergleichsnamen mit namen_sammeln() vorbereiten
namen1 = namen_sammeln(dateien1, mit_endung)
namen2 = namen_sammeln(dateien2, mit_endung)
Diese Funktion erhält die Dateiliste und die Einstellung zur Endung. Sie erstellt mit {} ein leeres Dictionary. Ein Dictionary ordnet einem Schlüssel einen Wert zu. Wir verwenden den vorbereiteten Namen als Schlüssel und die ursprüngliche Schreibweise als Wert.
name = datei.name if mit_endung else datei.stem
namen.setdefault(name.casefold(), name)
Der bedingte Ausdruck wählt den vollständigen Namen oder den Basisnamen aus. setdefault() fügt den Schlüssel mit dem angegebenen Wert nur hinzu, wenn dieser Schlüssel noch nicht vorhanden ist. Ein bereits vorhandener Eintrag bleibt erhalten. So bewahren wir für die Anzeige die Schreibweise des ersten erfassten Namens.
Liegen Bild.jpg und Bild.png im selben Ordner, ergeben sie ohne Endung beide den Vergleichsschlüssel bild. Das sind zwei Dateien, aber nur ein Vergleichsname. Deshalb unterscheiden wir im Bericht Dateianzahlen und fehlende Namen.
List Comprehensions: Welche Namen fehlen?
fehlt1 = [name for schluessel, name in namen2.items() if schluessel not in namen1]
fehlt2 = [name for schluessel, name in namen1.items() if schluessel not in namen2]
Die eckigen Klammern erzeugen jeweils eine neue Liste. Diese kompakte Schreibweise heißt List Comprehension. Zum Verstehen beginnen wir beim for und schauen uns die erste Zeile auf mehrere Zeilen verteilt an:
fehlt1 = [
name
for schluessel, name in namen2.items()
if schluessel not in namen1
]
| Bestandteil | Bedeutung |
|---|---|
namen2.items() |
Liefert die Schlüssel-Wert-Paare aus dem zweiten Dictionary. |
for schluessel, name in ... |
Geht die Paare durch und verteilt jedes Paar auf die zwei Variablen. |
if schluessel not in namen1 |
Übernimmt nur Einträge, deren Schlüssel im ersten Dictionary fehlt. |
name am Anfang |
Bestimmt den Wert, der in die neue Liste aufgenommen wird. |
fehlt1 = ... |
Speichert die fertige Liste der Namen, die im ersten Ordner fehlen. |
Bei einem Dictionary prüfen in und not in die Schlüssel. Die Bedingung sucht also nicht nach einem Teil eines Dateinamens und auch nicht in den gespeicherten Werten. Sie prüft, ob genau dieser Vergleichsschlüssel vorhanden ist. Für die Ausgabe übernehmen wir anschließend den zugehörigen ursprünglichen Namen.
namen1 = {"bild_001": "Bild_001", "bild_002": "Bild_002"}
namen2 = {"bild_001": "Bild_001", "bild_003": "Bild_003"}
Der Schlüssel bild_001 ist in beiden Dictionaries vorhanden und wird nicht in die Fehlstellenliste aufgenommen. bild_003 fehlt dagegen in namen1. Deshalb entsteht:
fehlt1 = ["Bild_003"]
Dieselbe Aufgabe lässt sich mit einer gewöhnlichen Schleife schreiben:
fehlt1 = []
for schluessel, name in namen2.items():
if schluessel not in namen1:
fehlt1.append(name)
Wir legen eine leere Liste an, prüfen die Einträge und hängen einen Namen nur dann an, wenn sein Schlüssel im ersten Dictionary fehlt. Die List Comprehension fasst genau diesen Ablauf kürzer zusammen.
Für fehlt2 tauschen wir die Dictionaries aus: Nun prüfen wir Namen aus Ordner 1 gegen Ordner 2. Im Beispiel ergibt sich fehlt2 = ["Bild_002"]. Die Zahl im Variablennamen bezeichnet also immer den Ordner, in dem etwas fehlt.
Den Bericht zusammenstellen und anzeigen
bericht = [
"Dateien aus Ordner 2, die in Ordner 1 fehlen:",
*fehlt1,
"",
f"Fehlende Namen in Ordner 1: {len(fehlt1)}",
]
Die Berichtszeilen liegen ebenfalls in einer Liste. *fehlt1 packt die Namen einzeln in diese äußere Liste aus. Ohne Sternchen würde die gesamte Liste als ein einzelnes verschachteltes Element eingefügt. Der leere String "" erzeugt später eine Leerzeile. len() liefert die Anzahl der Elemente.
print("\n".join(bericht))
join() verbindet die Textzeilen zu einem zusammenhängenden String. Zwischen je zwei Einträgen wird hier ein Zeilenumbruch eingefügt. print() zeigt diesen Text an.
Im Echtmodus: Zeitstempel, Zielpfad und Speichern
zeitstempel = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
ausgabe = Path(__file__).resolve().parent / f"vergleich_ergebnis_{zeitstempel}.txt"
bericht_speichern(ausgabe, bericht)
datetime.now() liefert die aktuelle lokale Zeit. strftime() formatiert sie als Jahr, Monat, Tag, Stunde, Minute und Sekunde. __file__ bezeichnet diese Python-Datei. resolve() ermittelt den aufgelösten absoluten Pfad und parent dessen übergeordneten Ordner. Mit / hängen wir den Berichtsnamen an.
def bericht_speichern(pfad, zeilen):
with pfad.open("x", encoding="utf-8") as datei:
datei.write("\n".join(zeilen) + "\n")
Die Funktion erhält den Zielpfad und die Berichtszeilen. Der Modus "x" erstellt eine neue Datei und löst einen Fehler aus, wenn sie schon existiert. encoding="utf-8" legt die Textkodierung fest. with sorgt dafür, dass die geöffnete Datei beim Verlassen des Blocks geschlossen wird, auch bei einem Fehler. write() schreibt den verbundenen Text.
Der Zeitstempel hat eine Genauigkeit von einer Sekunde. Zwei Durchläufe innerhalb derselben Sekunde können deshalb denselben Berichtsnamen ergeben. In diesem Fall schützt "x" den bereits vorhandenen Bericht vor dem Überschreiben.
Fehler behandeln und zum Startblock zurückkehren
Der try-Block enthält den normalen Ablauf. except (OSError, ValueError, EOFError) as fehler fängt die angegebenen Fehlerarten ab: beispielsweise Dateizugriffsfehler, ungültige Eingaben oder eine beendete Eingabe. Der Fehlertext wird angezeigt und main() gibt 1 zurück. Bei erfolgreicher Verarbeitung gibt die Funktion 0 zurück. Anschließend erhält sys.exit() diesen Wert.
3. Starter-Batchdatei der normalen Variante
@echo off
setlocal DisableDelayedExpansion
REM ============================================================
REM TOPTORIALS OFFICE - Python Grundkurs Teil 010
REM Beschreibung: Startet den Vergleich zweier Ordner.
REM Autor: Chris
REM YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
REM Webseite: https://www.toptorials.com
REM Version: Grundkurs 1.0 - Stand: 2026-09-16
REM
REM Mit _test im Namen: keine Ergebnisdateien erstellen.
REM Ohne _test im Namen: Ergebnisberichte speichern.
REM Python 3 und Python Launcher py werden benoetigt.
REM Die Python-Datei muss neben dieser Batchdatei liegen.
REM Die Vergleichsordner werden in der Python-Datei eingetragen.
REM Der Name der echten Batchdatei steuert den Testmodus.
REM Nutzung auf eigene Verantwortung. Zuerst mit Testdaten pruefen.
REM ============================================================
chcp 65001 >nul
set "STARTERNAME=%~n0"
set "TESTPARAMETER="
if /i not "%STARTERNAME:_test=%"=="%STARTERNAME%" set "TESTPARAMETER=--test"
py -3 -X utf8 "%~dp0010_fehlende_dateien_vergleichen.py" %TESTPARAMETER%
set "EXITCODE=%ERRORLEVEL%"
echo.
pause
exit /b %EXITCODE%
@echo off unterdrückt die zusätzliche Anzeige der Befehle. setlocal DisableDelayedExpansion begrenzt Variableneinstellungen auf den Starter und deaktiviert die verzögerte Variablenersetzung. Dadurch werden Ausrufezeichen in übergebenen Pfaden nicht als solche Variablenmarkierungen verarbeitet. chcp 65001 stellt die Konsolencodepage auf UTF-8.
Den Testmodus ohne find erkennen
set "STARTERNAME=%~n0"
set "TESTPARAMETER="
if /i not "%STARTERNAME:_test=%"=="%STARTERNAME%" set "TESTPARAMETER=--test"
%~n0 liefert den Namen dieser Batchdatei ohne Erweiterung. TESTPARAMETER beginnt leer. Für den Vergleich wird links _test probeweise durch einen leeren Text ersetzt. Rechts steht der unveränderte Name. Sind die beiden Texte ungleich, war _test enthalten und der Testparameter wird gesetzt. /i macht den Vergleich unabhängig von Groß-/Kleinschreibung.
Ursprünglicher Name: 010_vergleichen_starter_batch_test
Vergleich links: 010_vergleichen_starter_batch
Vergleich rechts: 010_vergleichen_starter_batch_test
Merksatz:
Wir entfernen _test probeweise aus dem Starternamen. Unterscheidet sich das Ergebnis vom ursprünglichen Namen, war _test enthalten und der Testmodus wird aktiviert.
Dabei wird weder die Batchdatei umbenannt noch der Inhalt von STARTERNAME dauerhaft verändert. Die Ersetzung liefert nur den Text für diesen Vergleich.
Die bisherige Lösung mit find konnte dieselbe Aufgabe erfüllen. Hier brauchen wir dafür keine Pipe und kein zusätzlich gestartetes find.exe. Die direkte Ersetzung ist kompakter; ein spürbarer Geschwindigkeitsvorteil ist bei diesen kleinen Startern nicht entscheidend.
Python aufrufen und den Rückgabecode übernehmen
py -3 -X utf8 "%~dp0010_fehlende_dateien_vergleichen.py" %TESTPARAMETER%
py -3 startet Python 3 über den Windows-Launcher. -X utf8 aktiviert den UTF-8-Modus. %~dp0 liefert den Ordner der Batchdatei einschließlich des abschließenden Backslashes. Direkt danach folgt der Python-Dateiname. Die Anführungszeichen halten einen Pfad mit Leerzeichen zusammen. Am Ende wird je nach Modus --test oder kein zusätzlicher Text eingesetzt.
%ERRORLEVEL% wird unmittelbar nach dem Python-Aufruf in EXITCODE gespeichert. echo. erzeugt eine Leerzeile und pause hält das Fenster offen. exit /b %EXITCODE% beendet danach den Starter mit dem zuvor gespeicherten Status.
4. SendTo einrichten und ausprobieren
- Lasst Python-Datei und Starter im Ordner
02_SendTo_Zwei_Ordner_vergleichen. - Erstellt Verknüpfungen zu den beiden Starter-Batchdateien.
- Öffnet
shell:sendtoin der Adresszeile des Explorers und legt die Verknüpfungen dort ab. - Markiert genau zwei Vergleichsordner und wählt Rechtsklick – Senden an – den Teststarter.
- Vergleicht zuerst mit JA, anschließend mit NEIN. Fügt das Ergebnis mit Strg+V in einen Texteditor ein.
- Startet ohne _test und kontrolliert den Bericht in jedem ausgewählten Ordner.
Verknüpfungen zu den Startern verwenden.
Kopiert nicht nur die Batchdateien in den SendTo-Ordner: Der Starter erwartet die Python-Datei neben sich. Der Name der echten Starterdatei steuert den Modus, nicht der Anzeigename ihrer Verknüpfung.
Als Vergleichsziele erwartet diese Version zwei Dateisystemordner. Windows-Verknüpfungen zu Ordnern, also .lnk-Dateien, werden nicht aufgelöst. Für die gemeinsame Auswahl im Explorer legt ihr die beiden Testordner am besten in dasselbe übergeordnete Verzeichnis.
Ordner_A/vergleich_fehlt_hier_2026-09-16_14-30-00.txt
Ordner_B/vergleich_fehlt_hier_2026-09-16_14-30-00.txt
Jeder Bericht zeigt die Namen, die in seinem eigenen Ordner fehlen. Vorhandene Dateien nach dem Muster vergleich_fehlt_hier_*.txt werden beim SendTo-Vergleich ausgeschlossen. Das verhindert, dass frühere Berichte spätere Vergleiche beeinflussen. Der Filter erkennt jedoch nur den Namen: Auch eine selbst erstellte Datei mit einem solchen Namen wird ausgeschlossen. Die normale Variante aktiviert diesen Filter nicht.
Vollständiges Python-Skript: SendTo
# ============================================================
# TOPTORIALS OFFICE - Python Grundkurs Teil 010
# Script: 010_sendto_zwei_ordner_vergleichen.py
# Beschreibung:
# Vergleicht genau zwei übergebene Ordner.
# Vergleich anhand der Dateinamen, wahlweise ohne letzte Endung.
# Groß-/Kleinschreibung wird ignoriert. Kein Inhaltsvergleich.
# Nur direkt enthaltene Dateien, einschließlich versteckter Dateien.
# Unterordner werden nicht durchsucht.
#
# Autor: Chris
# YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
# Webseite: https://www.toptorials.com
# Version: Grundkurs 1.0
# Stand: 2026-09-16
#
# Hinweise:
# Mit _test im Starternamen wird --test übergeben:
# Ergebnis anzeigen, aber keine Ergebnisdateien erstellen.
# Ohne _test werden zusätzlich Berichte mit Zeitstempel gespeichert.
# Bestehende gleichnamige Berichte werden nicht überschrieben.
# SendTo: Bericht je Ordner; Zwischenablage auch im Testmodus.
# Zuerst mit Testdaten arbeiten. Nutzung auf eigene Verantwortung.
# ============================================================
from datetime import datetime
from pathlib import Path
import sys
import subprocess
def dateien_einlesen(ordner, berichte_ausschliessen=False):
dateien = []
for datei in ordner.iterdir():
if not datei.is_file():
continue
name = datei.name.casefold()
if berichte_ausschliessen and name.startswith("vergleich_fehlt_hier_") and name.endswith(".txt"):
continue
dateien.append(datei)
return sorted(dateien, key=lambda datei: datei.name.casefold())
def namen_sammeln(dateien, mit_endung):
# Der Vergleichsschlüssel ignoriert Groß- und Kleinschreibung.
# Als Wert bleibt die ursprüngliche Schreibweise erhalten.
namen = {}
for datei in dateien:
name = datei.name if mit_endung else datei.stem
namen.setdefault(name.casefold(), name)
return namen
def bericht_speichern(pfad, zeilen):
# "x" erstellt eine neue Datei und verhindert das Überschreiben.
with pfad.open("x", encoding="utf-8") as datei:
datei.write("\n".join(zeilen) + "\n")
def bericht_erstellen(dieser_ordner, anderer_ordner, eingabe, anzahl, andere_anzahl, fehlt):
return [
"Vergleichsergebnis", "",
f"Dieser Ordner: {dieser_ordner}",
f"Vergleich mit: {anderer_ordner}",
f"Dateiendung berücksichtigen: {eingabe}", "",
"Dateien, die in diesem Ordner fehlen:",
*fehlt, "", "Zusammenfassung:",
f"Dateien in diesem Ordner: {anzahl}",
f"Dateien im Vergleichsordner: {andere_anzahl}",
f"Fehlende Namen in diesem Ordner: {len(fehlt)}",
]
def zwischenablage_kopieren(text):
# clip.exe erwartet Unicode-Text hier als UTF-16LE.
subprocess.run(["clip.exe"], input=text.encode("utf-16le"), check=True)
def main():
try:
argumente = sys.argv[1:]
test = "--test" in argumente
elemente = [wert for wert in argumente if wert != "--test"]
if len(elemente) != 2:
raise ValueError("Bitte genau zwei Ordner über Senden an übergeben.")
ordner1, ordner2 = [Path(wert).resolve() for wert in elemente]
for ordner in (ordner1, ordner2):
if not ordner.is_dir():
raise ValueError(f"Kein Dateisystemordner: {ordner}")
if ordner1.samefile(ordner2):
raise ValueError("Bitte zwei unterschiedliche Ordner auswählen.")
print(f"\nTestmodus: {'JA' if test else 'NEIN'}\n")
print(f"Ordner 1: {ordner1}")
print(f"Ordner 2: {ordner2}\n")
print("JA = vollständigen Dateinamen vergleichen")
print("NEIN = Dateiendung ignorieren\n")
eingabe = input("Dateiendung berücksichtigen? JA/NEIN: ").strip().upper()
if eingabe not in ("JA", "NEIN"):
raise ValueError("Bitte JA oder NEIN eingeben.")
mit_endung = eingabe == "JA"
dateien1 = dateien_einlesen(ordner1, berichte_ausschliessen=True)
dateien2 = dateien_einlesen(ordner2, berichte_ausschliessen=True)
namen1 = namen_sammeln(dateien1, mit_endung)
namen2 = namen_sammeln(dateien2, mit_endung)
fehlt1 = [name for schluessel, name in namen2.items() if schluessel not in namen1]
fehlt2 = [name for schluessel, name in namen1.items() if schluessel not in namen2]
bericht1 = bericht_erstellen(ordner1, ordner2, eingabe, len(dateien1), len(dateien2), fehlt1)
bericht2 = bericht_erstellen(ordner2, ordner1, eingabe, len(dateien2), len(dateien1), fehlt2)
gesamt = "\n".join(bericht1 + ["", "-" * 60, ""] + bericht2)
print("\n" + gesamt + "\n")
# Die Zwischenablage wird in beiden Modi aktualisiert.
try:
zwischenablage_kopieren(gesamt.replace("\n", "\r\n"))
print("Die Berichte wurden in die Zwischenablage kopiert.")
except (OSError, subprocess.SubprocessError) as fehler:
print(f"Hinweis: Zwischenablage konnte nicht aktualisiert werden: {fehler}")
if test:
print("Testmodus: Es wurden keine Ergebnisdateien erstellt.")
else:
zeitstempel = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
dateiname = f"vergleich_fehlt_hier_{zeitstempel}.txt"
for ordner, bericht in ((ordner1, bericht1), (ordner2, bericht2)):
ausgabe = ordner / dateiname
bericht_speichern(ausgabe, bericht)
print(f"Ergebnisdatei erstellt: {ausgabe}")
return 0
except (OSError, ValueError, EOFError) as fehler:
print(f"\nFehler: {fehler}")
return 1
if __name__ == "__main__":
sys.exit(main())
5. Die zusätzlichen SendTo-Funktionen verstehen
Argumente sammeln und zwei Ordner prüfen
elemente = [wert for wert in argumente if wert != "--test"]
ordner1, ordner2 = [Path(wert).resolve() for wert in elemente]
Die erste List Comprehension übernimmt alle Argumente außer --test. Anschließend prüft das Skript, ob genau zwei Elemente vorhanden sind. Erst dann wandelt die zweite List Comprehension beide Texte in aufgelöste Pfadobjekte um. Die beiden Ergebnisse werden durch Entpacken auf ordner1 und ordner2 verteilt.
Wie zuvor prüft is_dir(), ob beide Pfade Ordner sind. Mit samefile() prüfen wir außerdem, ob beide Pfade auf denselben Dateisystemeintrag zeigen. In diesem Fall wird der Vergleich mit einer verständlichen Meldung abgebrochen.
Die Dateiliste ohne alte Berichte einlesen
dateien1 = dateien_einlesen(ordner1, berichte_ausschliessen=True)
Jetzt nutzen wir bewusst das zweite Argument unserer bereits bekannten Funktion. Weil es True ist, wird die Prüfung mit startswith() und endswith() wirksam. Ein Name muss mit vergleich_fehlt_hier_ beginnen und mit .txt enden, damit die Datei übersprungen wird. Namen sammeln und fehlende Namen ermitteln funktioniert danach wie in der normalen Variante.
Argumente und Parameter von bericht_erstellen()
def bericht_erstellen(dieser_ordner, anderer_ordner, eingabe, anzahl, andere_anzahl, fehlt):
bericht1 = bericht_erstellen(
ordner1,
ordner2,
eingabe,
len(dateien1),
len(dateien2),
fehlt1
)
Die Definition benennt die Parameter, mit denen die Funktion intern arbeitet. Beim Aufruf übergeben wir konkrete Argumente. Hier werden sie anhand ihrer Position zugeordnet: erstes Argument zum ersten Parameter, zweites zum zweiten und so weiter. Die Namen der Variablen beim Aufruf müssen dafür nicht mit den Parameternamen übereinstimmen.
| Argument beim ersten Aufruf | Parameter in der Funktion | Bedeutung |
|---|---|---|
ordner1 |
dieser_ordner |
Der Ordner, dessen fehlende Namen wir beschreiben |
ordner2 |
anderer_ordner |
Der Vergleichsordner |
eingabe |
eingabe |
JA oder NEIN zur Dateiendung |
len(dateien1) |
anzahl |
Dateianzahl dieses Ordners |
len(dateien2) |
andere_anzahl |
Dateianzahl des Vergleichsordners |
fehlt1 |
fehlt |
Liste der Namen, die hier fehlen |
len(dateien1) und len(dateien2) werden berechnet, bevor die Berichtsfunktion ausgeführt wird. Die Funktion bekommt hier also die ermittelten Zahlen. fehlt1 ist dagegen die Liste der fehlenden Namen. Mit return [...] gibt die Funktion eine Liste fertiger Berichtszeilen zurück. Diese Rückgabe landet in bericht1.
bericht2 = bericht_erstellen(
ordner2,
ordner1,
eingabe,
len(dateien2),
len(dateien1),
fehlt2
)
Beim zweiten Aufruf wechseln wir die Perspektive. Nun ist Ordner 2 dieser_ordner. Deshalb tauschen wir auch die beiden Dateianzahlen und übergeben fehlt2. Die Einstellung zur Dateiendung bleibt gleich. Beide Berichte verwenden dadurch dieselbe Vorlage, die nur an einer Stelle gepflegt werden muss.
Als Lernvergleich lässt sich der erste Aufruf auch mit benannten Argumenten schreiben:
bericht1 = bericht_erstellen(
dieser_ordner=ordner1,
anderer_ordner=ordner2,
eingabe=eingabe,
anzahl=len(dateien1),
andere_anzahl=len(dateien2),
fehlt=fehlt1
)
Damit wird die Zuordnung direkt sichtbar. In den vollständigen Skripten oben bleibt die kompakte Positionsschreibweise erhalten. Durch die geöffneten runden Klammern darf Python den Aufruf über mehrere Zeilen fortsetzen; zusätzliche Zeichen zur Zeilenfortsetzung werden hier nicht gebraucht.
Berichte verbinden und in die Zwischenablage kopieren
gesamt = "\n".join(bericht1 + ["", "-" * 60, ""] + bericht2)
Das Pluszeichen verbindet die drei Listen zu einer Liste. "-" * 60 erzeugt eine Trennlinie aus 60 Bindestrichen. join() verbindet die Zeilen anschließend zu einem Text für Anzeige und Zwischenablage.
zwischenablage_kopieren(gesamt.replace("\n", "\r\n"))
def zwischenablage_kopieren(text):
subprocess.run(["clip.exe"], input=text.encode("utf-16le"), check=True)
Vor dem Aufruf ersetzen wir die verwendeten Zeilenumbrüche durch Windows-Zeilenumbrüche. Die Funktion startet mit subprocess.run() das Windows-Programm clip.exe. encode("utf-16le") wandelt den Text in die dafür übergebenen Bytes um. Über input gelangen sie an die Standardeingabe des Programms. check=True lässt einen Fehler auslösen, wenn das Programm einen von null verschiedenen Rückgabecode liefert.
Ein eigener try/except-Bereich behandelt Fehler der Zwischenablage. Dann erscheint ein Hinweis, aber der Vergleich und das mögliche Speichern können weiterlaufen. Der Aufruf steht vor der Unterscheidung zwischen Test- und Echtmodus. Deshalb wird die Zwischenablage in beiden Modi aktualisiert.
Für jeden Ordner den passenden Bericht speichern
for ordner, bericht in ((ordner1, bericht1), (ordner2, bericht2)):
ausgabe = ordner / dateiname
bericht_speichern(ausgabe, bericht)
Hier durchlaufen wir zwei Paare. Im ersten Durchlauf stehen ordner1 und bericht1 in den Schleifenvariablen. Im zweiten Durchlauf sind es ordner2 und bericht2. Das gemeinsame dateiname wird an den jeweiligen Ordner angehängt. Unsere bereits erklärte Speicherfunktion schreibt dann den passenden Bericht.
Die Dateien werden nacheinander geschrieben. Falls der zweite Schreibvorgang fehlschlägt, bleibt der erste erfolgreich erstellte Bericht bestehen. Eine bereits vorhandene gleichnamige Datei wird durch den Modus "x" geschützt.
6. Starter-Batchdatei für SendTo
@echo off
setlocal DisableDelayedExpansion
REM ============================================================
REM TOPTORIALS OFFICE - Python Grundkurs Teil 010
REM Beschreibung: Startet den Vergleich zweier Ordner.
REM Autor: Chris
REM YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
REM Webseite: https://www.toptorials.com
REM Version: Grundkurs 1.0 - Stand: 2026-09-16
REM
REM Mit _test im Namen: keine Ergebnisdateien erstellen.
REM Ohne _test im Namen: Ergebnisberichte speichern.
REM Python 3 und Python Launcher py werden benoetigt.
REM Die Python-Datei muss neben dieser Batchdatei liegen.
REM SendTo: Verknuepfung hierher anlegen; genau zwei Ordner senden.
REM Zwischenablage wird auch im Testmodus aktualisiert.
REM Der Name der echten Batchdatei steuert den Testmodus.
REM Nutzung auf eigene Verantwortung. Zuerst mit Testdaten pruefen.
REM ============================================================
chcp 65001 >nul
set "STARTERNAME=%~n0"
set "TESTPARAMETER="
if /i not "%STARTERNAME:_test=%"=="%STARTERNAME%" set "TESTPARAMETER=--test"
py -3 -X utf8 "%~dp0010_sendto_zwei_ordner_vergleichen.py" %TESTPARAMETER% %*
set "EXITCODE=%ERRORLEVEL%"
echo.
pause
exit /b %EXITCODE%
Der Aufbau entspricht dem normalen Starter. Zusätzlich steht am Ende des Python-Aufrufs %*. Damit reicht die Batchdatei alle übergebenen Argumente weiter. Bei der gewünschten Explorer-Auswahl sind das die beiden Ordnerpfade. Das Python-Skript prüft anschließend selbst, ob genau zwei gültige, unterschiedliche Ordner übergeben wurden.
Häufige Fragen und mögliche Fehler
| Beobachtung | Erklärung oder Lösung |
|---|---|
| py wird nicht gefunden | Python-Launcher prüfen oder py -3 im Starter durch python ersetzen. |
| Ordner nicht gefunden | Die festen Pfade kontrollieren; die Testordner müssen bereits existieren. |
| Python-Datei wird über SendTo nicht gefunden | Verknüpfung zum echten Starter verwenden; Python-Datei muss neben dem Starter liegen. |
| Weniger fehlende Namen als Dateien | Ohne Endung können mehrere Dateien denselben Vergleichsnamen ergeben. |
| Ein alter SendTo-Bericht fehlt in der Dateiliste | Dateien mit dem reservierten Muster vergleich_fehlt_hier_*.txt werden ausgeschlossen. |
| Kein Bericht im Testmodus | Das ist vorgesehen. Ohne _test im tatsächlichen Starternamen werden Berichte gespeichert. |
| Zwischenablage enthält neuen Text trotz Testmodus | SendTo aktualisiert sie in beiden Modi. |
| FileExistsError beim Speichern | Ein gleichnamiger Bericht existiert bereits; er wird nicht überschrieben. |
| Nur ein SendTo-Bericht wurde erstellt | Das Speichern erfolgt nacheinander; die Fehlermeldung zum zweiten Ziel prüfen. |
Zusammenfassung
- Zwei Ordner werden anhand ihrer Dateinamen in beide Richtungen verglichen.
- JA berücksichtigt die Endung, NEIN verwendet den Basisnamen.
- Funktionen teilen den Ablauf in verständliche Aufgaben auf.
- Der Startblock ruft main() auf und gibt den Rückgabecode weiter.
- Ein Standardwert macht ein Argument beim Aufruf optional.
- Dictionaries speichern Vergleichsschlüssel und ursprüngliche Namen.
- List Comprehensions erzeugen die beiden Listen fehlender Namen.
- Die Berichtsfunktion wird bei SendTo mit vertauschten Argumenten wiederverwendet.
- Im Testmodus werden keine Berichte gespeichert; SendTo aktualisiert trotzdem die Zwischenablage.
- Im Echtmodus landet der normale Bericht im Skriptordner, die SendTo-Berichte in den ausgewählten Ordnern.
- Bestehende gleichnamige Berichte werden nicht überschrieben.
Damit habt ihr zwei praktische Varianten zum Ordnervergleich und zugleich einen Einblick in den Aufbau von Python-Skripten mit mehreren Funktionen. Probiert die verschiedenen Vergleichseinstellungen mit den Testdaten aus und verfolgt dabei, welche Werte zwischen den Funktionen übergeben werden.
Video zu diesem Tutorial:
Das könnte Dich auch interessieren
Keine Einträge gefunden

