Anhang B - The Zen of Python
Anhang B: The Zen of Python
Abschnitt betitelt „Anhang B: The Zen of Python“Python trägt seine Design-Philosophie als Osterei in sich. Wer in der REPL import this eintippt, bekommt ein Gedicht:
>>> import thisThe Zen of Python, by Tim Peters...Der Text stammt von Tim Peters, einem der prägenden Python-Entwickler der ersten Stunde, und wurde 1999 als halb ernste, halb augenzwinkernde Zusammenfassung der Entwurfsprinzipien der Sprache formuliert. Seit 2004 ist er offiziell als PEP 20 dokumentiert (PEPs, Python Enhancement Proposals, sind die nummerierten Design-Dokumente der Python-Gemeinschaft; PEP 8 mit den Stilregeln kennen Sie bereits). Der Zen beschreibt im Kern, woran die Sprache selbst gemessen wurde; er taugt aber genauso als Maßstab für eigenen Code und wird in der Praxis ständig zitiert, in Code-Reviews ebenso wie in Diskussionen über Bibliotheks-Design.
Der Volltext
Abschnitt betitelt „Der Volltext“The Zen of Python, by Tim Peters
Beautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than complicated.Flat is better than nested.Sparse is better than dense.Readability counts.Special cases aren't special enough to break the rules.Although practicality beats purity.Errors should never pass silently.Unless explicitly silenced.In the face of ambiguity, refuse the temptation to guess.There should be one-- and preferably only one --obvious way to do it.Although that way may not be obvious at first unless you're Dutch.Now is better than never.Although never is often better than *right* now.If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.Namespaces are one honking great idea -- let's do more of those!Auffällig: Es sind 19 Zeilen, obwohl die Einleitung von PEP 20 von 20 Aphorismen spricht. Die zwanzigste Zeile wurde nie geschrieben; auch das gehört zum Witz des Textes.
Zeile für Zeile
Abschnitt betitelt „Zeile für Zeile“Beautiful is better than ugly. Der Einstieg legt die Grundhaltung fest: Ästhetik von Code ist kein Luxus, sondern ein Qualitätsmerkmal. “Schön” meint hier nicht dekorativ, sondern klar geformt: konsistente Namen, erkennbare Struktur, nichts Überflüssiges. Hässlicher Code funktioniert oft genauso, aber niemand liest ihn gern, und was niemand gern liest, wird schlecht gewartet.
Explicit is better than implicit.
Code soll aussprechen, was er tut, statt auf verstecktes Verhalten zu bauen. Ein Python-Beispiel steckt in jeder Methode: self steht sichtbar in der Parameterliste, während andere Sprachen den Objektbezug unsichtbar bereitstellen. Für eigenen Code heißt das etwa: from module import * vermeiden (woher kommt dieser Name?), Parameter beim Aufruf benennen (scale(1920, 1080, factor=0.5)), keine Wirkung im Verborgenen.
Simple is better than complex. Wenn eine einfache Lösung das Problem löst, ist sie der komplexen vorzuziehen. Eine Funktion mit drei Zeilen schlägt eine Klassenhierarchie, wenn drei Zeilen genügen. Komplexität muss man sich durch ein Problem verdienen, das sie wirklich erfordert.
Complex is better than complicated. Das Gegenstück dazu: Manche Probleme sind komplex, und dann darf die Lösung es auch sein. Der Unterschied liegt zwischen komplex (viele Teile, aber geordnet und nachvollziehbar) und kompliziert (verworren, undurchschaubar, voller Sonderfälle). Eine sauber entworfene Klassenhierarchie mit zehn Klassen ist komplex; eine 300-Zeilen-Funktion mit acht Verschachtelungsebenen ist kompliziert.
Flat is better than nested.
Tiefe Verschachtelung (Schleife in Schleife in if in if) ist schwer zu verfolgen. Flacher wird Code etwa durch frühe Rückkehr (if not valid: return statt den ganzen Rumpf einzurücken), durch das Auslagern innerer Blöcke in Funktionen und durch elif-Ketten statt geschachtelter if/else-Treppen.
Sparse is better than dense. Lieber mehrere klare Zeilen als eine überfrachtete. Ein Einzeiler, der Filterung, Umwandlung, Sortierung und Ausgabe zugleich erledigt, spart Platz und kostet jeden Leser Minuten. Luft im Code (eine Anweisung pro Zeile, Leerzeilen zwischen Sinnabschnitten) ist erwünscht.
Readability counts. Die meistzitierte Zeile und das Herzstück. Code wird einmal geschrieben und viele Male gelesen, von Kolleginnen, Korrektoren und vom eigenen zukünftigen Ich. Lesbarkeit ist deshalb keine Geschmacksfrage, sondern ein ökonomisches Argument: Sie entscheidet über die Kosten jeder künftigen Änderung. Praktisch alles in Anhang A ist eine Anwendung dieser Zeile.
Special cases aren’t special enough to break the rules. Konsistenz hat Vorrang. Wer für einen vermeintlichen Sonderfall die Namenskonvention bricht, ein globales Flag einführt oder die Schichtentrennung durchlöchert, bezahlt dafür bei jeder späteren Änderung. Erst einmal davon ausgehen, dass die bestehende Regel auch den Sonderfall trägt.
Although practicality beats purity. Die sofortige Selbstkorrektur: Regeln sind Mittel, nicht Selbstzweck. Wenn die reine Lehre zu absurdem Aufwand führt, gewinnt die pragmatische Lösung. Die Kunst liegt darin, diese Ausnahme selten und begründet zu ziehen, sonst hebelt sie die vorige Zeile komplett aus. Ein Beispiel aus dem Unterricht: Die pragmatische E-Mail-Prüfung per einfacher Regex schlägt das standardkonforme Monstermuster (Kapitel 3).
Errors should never pass silently.
Ein verschluckter Fehler ist der teuerste Fehler: Das Programm rechnet mit falschen Werten weiter, und der Schaden zeigt sich weit weg von der Ursache. Deshalb sind Exceptions laut (Kapitel 7), und deshalb ist except: pass das Anti-Muster schlechthin. Ein sichtbarer Absturz ist einem unsichtbar falschen Ergebnis immer vorzuziehen.
Unless explicitly silenced.
Auch hier die Ausnahme: Es gibt legitime Gründe, einen bestimmten Fehler bewusst zu ignorieren (eine fehlende Konfigurationsdatei bedeutet eben “Standardwerte”). Entscheidend ist das Wort explicitly: ein konkreter Exception-Typ, eine bewusste Entscheidung, idealerweise ein Kommentar mit dem Warum. except FileNotFoundError: config = {} ist explizites Schweigen; except: pass ist Vertuschung.
In the face of ambiguity, refuse the temptation to guess.
Wenn unklar ist, was gemeint ist, soll Software nicht raten, sondern nachfragen oder ablehnen. Python selbst lebt das vor: 1 + "2" löst einen TypeError aus, statt zu raten, ob 3 oder “12” gemeint war. Für eigene Programme heißt das: Mehrdeutige Eingaben zurückweisen (Kapitel 7), statt eine Interpretation zu erfinden, die in der Hälfte der Fälle falsch ist.
There should be one— and preferably only one —obvious way to do it. Ein bewusster Kontrast zu Sprachen, die für alles fünf gleichberechtigte Wege anbieten. Wenn es einen offensichtlichen Weg gibt, sieht Code verschiedener Autoren ähnlich aus, und genau das macht ihn gemeinsam wartbar. Für den Unterricht: Wer sich fragt, ob eine Lösung “erlaubt” ist, fragt besser, ob sie der offensichtliche Weg ist. (Die seltsam gesetzten Striche in dieser Zeile sind übrigens Absicht: Tim Peters parodiert damit uneinheitliche Zeichensetzung, ein Witz über Stilregeln mitten in einem Text über Stilregeln.)
Although that way may not be obvious at first unless you’re Dutch. Ein Insider-Witz: Pythons Erfinder Guido van Rossum ist Niederländer. Die Zeile gesteht ein, dass “offensichtlich” relativ ist; was für den Sprachdesigner offensichtlich war, muss man als Lernender manchmal erst nachschlagen. Die Botschaft dahinter ist ernst: Der offensichtliche Weg ist erlernbar, genau dafür existieren Dokumentation und Konventionen.
Now is better than never. Gegen die Endlos-Planung und den Perfektionismus: Eine lauffähige, unvollkommene Lösung heute schlägt die perfekte Lösung, die nie fertig wird. Anfangen, ausprobieren, verbessern; das iterative Arbeiten mit kleinen Commits (Kapitel 8) ist die praktische Form dieser Zeile.
Although never is often better than *right* now. Und wieder die Gegenkraft: Ein überstürzter Schnellschuss, der halb durchdacht in die Codebasis gelangt, richtet mehr Schaden an als eine Funktion, die es (noch) nicht gibt. Zusammen ergeben die beiden Zeilen ein Arbeitsprinzip: zügig liefern, aber nichts liefern, was man nicht verantworten kann. Der Test vor dem Commit ist die Grenze zwischen now und right now.
If the implementation is hard to explain, it’s a bad idea. Ein bemerkenswert praktischer Test für Entwurfsqualität: Erklären Sie Ihre Lösung einer Kollegin. Geht das nicht in wenigen Sätzen, ist meist nicht die Erklärung das Problem, sondern der Entwurf. Dieser Test ist der Grund, warum die Übungen dieses Jahrgangs so oft Begründungen und Erklärungen verlangen: Wer erklären muss, entdeckt die Schwächen selbst.
If the implementation is easy to explain, it may be a good idea. Die vorsichtige Umkehrung, mit Betonung auf may: Einfach erklärbar ist notwendig, aber nicht hinreichend. Auch eine leicht erklärbare Lösung kann falsch, langsam oder unsicher sein. Erklärbarkeit ist ein Filter, kein Gütesiegel.
Namespaces are one honking great idea — let’s do more of those!
Der bewusst alberne Schluss mit ernstem Kern: Namensräume halten Namen auseinander und Programme zusammensetzbar. In Python begegnen sie Ihnen überall: Jedes Modul ist ein Namensraum (storage.load_library sagt, wessen load_library gemeint ist, Kapitel 10), jede Klasse (Clip.fps), jede Funktion mit ihren lokalen Variablen. Deshalb gilt import module als besserer Stil als from module import *: Der Namensraum bleibt sichtbar, und genau das meint die Zeile.