1. September 2023 von Marc Mezger und Moritz Momper
Best Practices für Python-Entwicklungen, Teil 1 – Tools & Zen
In diesem Blog-Beitrag möchten wir unsere Best Practices für Python-Entwicklungen vorstellen. Python, als eine der meistgenutzten Programmiersprachen weltweit, bietet eine Vielzahl von Möglichkeiten, um Lösungen auf professionelle und effiziente Weise zu implementieren. Aber um das Potenzial von Python voll auszuschöpfen, ist es entscheidend, die Best Practices zu verstehen und anzuwenden. Best Practices sind bewährte Verfahren, die sich als besonders effektiv und produktiv in der Softwareentwicklung erwiesen haben. Sie dienen als Leitfaden, um den Code lesbar, wartbar und optimiert zu halten. Sie helfen uns nicht nur dabei, Fehler zu vermeiden, sondern fördern auch eine konsistente und qualitativ hochwertige Codebasis.
Was sind Best Practices?
Best Practices sind Leitlinien und Empfehlungen, die sich aus langjährigen Erfahrungen und Erkenntnissen in einem bestimmten Bereich, hier der Softwareentwicklung, herausgebildet haben. Sie repräsentieren die effektivsten und produktivsten Methoden, um Aufgaben in einer konsistenten und qualitativ hochwertigen Weise zu erfüllen. In der Softwareentwicklung beziehen sich Best Practices auf Techniken, Muster und Stile, die dazu beitragen, den Code sicherer, lesbarer, wartbarer und effizienter zu gestalten. Sie bilden quasi den Goldstandard, an dem sich Programmiererinnen und Programmierer orientieren können, um qualitativ hochwertige Software zu produzieren. Einige Best Practices sind sprachübergreifend gültig – etwa die Einhaltung bestimmter Style Guides oder das Schreiben von Unit-Tests. Andere sind spezifisch für eine bestimmte Programmiersprache, wie die Pythonic-Wege, um Dinge mit Python zu programmieren.
Es ist wichtig zu beachten, dass Best Practices nicht als starre Regeln betrachtet werden sollten, die in jedem Kontext angewendet werden müssen. Stattdessen dienen sie als Leitfaden, der helfen kann, fundierte Entscheidungen zu treffen und häufige Fehler zu vermeiden. Es kann Situationen geben, in denen das Abweichen von einer Best Practice gerechtfertigt ist, vorausgesetzt, die Entscheidung wird bewusst und nach sorgfältiger Abwägung getroffen.
Im Folgenden wollen wir euch unsere Tools für Best Practices, Codequalität und Entwicklung in Python vorstellen.
pyenv
pyenv ist ein unabhängiges Werkzeug zur Python-Version-Verwaltung. Es ermöglicht den Developern, mehrere Python-Versionen auf dem gleichen System zu installieren und zwischen ihnen zu wechseln. Mit pyenv können sie beispielsweise Python 3.10 für ein Projekt und Python 3.12 für ein anderes verwenden, ohne dass Konflikte zwischen den beiden Versionen entstehen. pyenv bietet eine einfache und intuitive Befehlsschnittstelle, um Python-Versionen zu installieren, zu deinstallieren, zu wechseln und zu verwalten. Es ermöglicht es auch, eine Python-Version pro Verzeichnis (über eine .python-version-Datei) oder pro Shell-Sitzung zu setzen. pyenv ist eine plattformübergreifende Lösung und kann auf den meisten Unix-ähnlichen Betriebssystemen verwendet werden, einschließlich Linux und macOS. Für Windows-Benutzerinnen und -Benutzer gibt es eine alternative Implementierung namens pyenv-win.
Wir bevorzugen pyenv über Anaconda, da es deutlich leichtgewichtiger ist und es eine deutlich größere Auswahl an Python-Versionen gibt. Außerdem interferiert pyenv nicht mit dem System Python, was bei Anaconda durchaus vorkommen kann.
Weitere Infos zu pyenv findet ihr hier:
Poetry
Poetry ist ein Werkzeug für die Verwaltung von Python-Projekten und -Abhängigkeiten. Es wurde entwickelt, um die Bereiche Verpackung, Veröffentlichung und Abhängigkeiten in Python zu vereinfachen und zu verbessern.
Mit Poetry könnt ihr neue Projekte erstellen, Abhängigkeiten hinzufügen und verwalten, eure Projekte veröffentlichen und viele andere Aufgaben erledigen, alle mit einer einzigen, konsistenten Schnittstelle.
Wie funktioniert Poetry?
Poetry verwendet die pyproject.toml-Datei, um die Konfiguration und die Abhängigkeiten eures Projekts zu speichern. Dies ist ein standardisiertes Format, das von PEP 518 eingeführt wurde und darauf abzielt, die Art und Weise, wie Python-Projekte verwaltet werden, zu vereinheitlichen.
Wenn ihr eine Abhängigkeit zu eurem Projekt hinzufügt, aktualisiert Poetry die pyproject.toml-Datei und erstellt oder aktualisiert eine poetry.lock-Datei. Diese .lock-Datei wird verwendet, um sicherzustellen, dass eure Abhängigkeiten konsistent sind und dass euer Projekt mit den gleichen Versionen der Abhängigkeiten auf verschiedenen Systemen und von verschiedenen Entwicklerinnen und Entwicklern ausgeführt wird. Durch die Speicherung von Hash-Werten wird sichergestellt, dass Änderungen an den Abhängigkeiten, die sich fälschlicherweise unter derselben Versionsnummer ausgeben, erkannt werden können. Diese Methode erhöht die Sicherheit und Zuverlässigkeit von Softwarepaketen, da sie eine konstante Übereinstimmung zwischen der erwarteten und der tatsächlich verwendeten Version der Abhängigkeit gewährleistet.
Poetry bietet eine festgelegte und reproduzierbare Dependency-Verwaltung, die sicherstellt, dass nur die angegebenen Pakete aus vertrauenswürdigen Quellen installiert werden, wodurch das Risiko einer „Package Confusion“-Attacke erheblich reduziert wird.
Poetry kann auch virtuelle Umgebungen für eure Projekte erstellen und verwalten, sodass ihr nicht selbst virtualenv oder ähnliche Werkzeuge verwenden müsst.
Es gibt viele Gründe, Poetry für die Verwaltung eurer Python-Projekte zu verwenden:
- 1. Einfache Verwaltung von Abhängigkeiten: Mit Poetry können Abhängigkeiten durch eineneinzigen Befehl hinzugefügt, aktualisiert oder entfernt werden. Das Tool kümmert sich auch um die Auflösung von Abhängigkeiten und stellt sicher, dass man keine inkonsistenten oder inkompatiblen Versionen von Paketen hat.
- 2. Einfache Veröffentlichung von Paketen: Poetry macht es einfach, Projekte auf PyPI oder anderen Paket-Indizes zu veröffentlichen. Es kann alle notwendigen Dateien erzeugen und ein Paket mit einem einzigen Befehl hochladen.
- 3. Verwaltung von virtuellen Umgebungen: Poetry kann automatisch virtuelle Umgebungen für Projekte erstellen und verwalten. Man muss sich nicht darum kümmern, virtualenv oder ähnliche Werkzeuge zu verwenden.
- 4. Konsistenz und Reproduzierbarkeit: Durch die Verwendung der pyproject.toml- und poetry.lock-Dateien stellt Poetry sicher, dass Projekte konsistent und reproduzierbar sind. Man kann sicher sein, dass ein Projekt auf verschiedenen Systemen und von verschiedenen Entwicklerinnen und Entwicklern genau gleich ausgeführt wird.
Insgesamt ist Poetry ein mächtiges und flexibles Werkzeug, das viele Aspekte der Python-Projektverwaltung vereinfacht und verbessert. Es ist eine hervorragende Wahl für Python nutzende Entwicklerinnen und Entwickler, die ihre Effizienz und Produktivität steigern möchten.
Weitere Infos zu Poetry findet ihr hier:
pre-commit
pre-commit ist ein Git-Hook-Framework für die Verwaltung und Wartung von pre-commit-Hooks. Git-Hooks sind Skripte, die vor oder nach Ereignissen wie Commit, Push und anderen ausgeführt werden. Diese Hooks werden verwendet, um Aufgaben zu automatisieren, die normalerweise manuell ausgeführt werden müssen.
Wie funktioniert pre-commit?
pre-commit arbeitet, indem es eine Konfigurationsdatei (üblicherweise pre-commit-config.yaml) im Projekt liest, die angibt, welche Hooks im Projekt verwendet werden sollen.
Ein Hook in diesem Kontext ist ein Skript oder Tool, das vor jedem Commit ausgeführt wird. Diese Hooks können eine Vielzahl von Aufgaben ausführen, wie beispielsweise das Überprüfen des Code-Stils (mit Tools wie flake8 oder black), das Suchen nach Syntaxfehlern, das Durchführen von statischen Code-Analysen oder sogar das Ausführen von Tests.
Wenn man versucht, einen Commit durchzuführen, wird pre-commit die entsprechenden Hooks ausführen. Wenn ein Hook fehlschlägt, etwa wenn flake8 einen Stilfehler findet, wird der Commit abgebrochen und man wird über das Problem informiert.
Es gibt mehrere Gründe, warum man pre-commit in den Entwicklungsprozess integrieren sollte:
- 1. Automatisierung der Code-Qualitäts-Prüfung: Mit pre-commit kann man sicherstellen, dass jeder Commit euren Qualitätsstandards entspricht, ohne dass man jedes Mal manuell Tools ausführen muss.
- 2. Vermeidung von Fehlern: Da pre-commit-Hooks vor dem eigentlichen Commit laufen, können sie dazu beitragen, dass Fehler nicht in den Code einfließen. Dies hilft, die Code-Qualität zu verbessern und die Zeit für die Fehlerbehebung zu reduzieren.
- 3. Konsistenz im Code: Tools wie black oder isort können als pre-commit-Hooks verwendet werden, um einen einheitlichen Code-Stil in eurem Projekt zu gewährleisten.
- 4. Integration in den Entwicklungsprozess: pre-commit kann in bestehende Entwicklungswerkzeuge und -prozesse integriert werden, einschließlich kontinuierlicher Integrationssysteme.
pre-commit ist ein leistungsfähiges Tool, das dabei helfen kann, die Code-Qualität zu verbessern und den Entwicklungsprozess zu beschleunigen. Es ist flexibel und anpassbar und kann eine Vielzahl von Hooks und Tools unterstützen, was es zu einem wertvollen Bestandteil jedes Python-Projekts macht.
Weitere Infos zu pre-commit findet ihr hier:
The Zen of Python – Leitprinzipien für die Python-Entwicklung
Das „Zen von Python“ ist eine Sammlung von 18 „Aphorismen“ oder Prinzipien, die als Leitfaden für das Schreiben von Computerprogrammen dienen und die die Python-Philosophie widerspiegeln. Tim Peters, ein langjähriger und bedeutender Python-Entwickler, hat diese Prinzipien verfasst. Sie können in Python selbst durch Eingabe von „import this“ in einem Python-Interpreter aufgerufen werden.
Hier sind die 18 Aphorismen:
- 1. Schön ist besser als hässlich: Dies betont die Bedeutung der Ästhetik im Code. Ein schöner Code ist leichter zu lesen und zu verstehen.
- 2. Explizit ist besser als implizit: Der Code sollte klar und direkt sein. Versteckte Bedeutungen oder Tricks machen den Code schwer zu verstehen und zu pflegen.
- 3. Einfach ist besser als komplex: Wenn es eine einfache Lösung für ein Problem gibt, verwenden Sie diese anstelle einer komplexeren.
- 4. Komplex ist besser als kompliziert: Komplexität ist unvermeidlich bei einigen Problemen, aber der Code sollte nie unnötig kompliziert sein.
- 5. Flach ist besser als verschachtelt: Tief verschachtelte Strukturen können schwer zu verstehen sein. Flache Strukturen sind in der Regel besser.
- 6. Übersichtlichkeit zählt: Ein lesbarer Code ist extrem wichtig, da er von Menschen gelesen und verstanden werden muss.
- 7. Sonderfälle sind nicht speziell genug, um die Regeln zu brechen: Es ist besser, konsistent zu bleiben und sich an die Regeln zu halten, anstatt Ausnahmen für bestimmte Spezialfälle zu machen.
- 8. Obwohl die Praxis die Reinheit schlägt: Praktische Lösungen sind oft besser als theoretisch „perfekte“ Lösungen.
- 9. Fehler sollten nie stillschweigend passieren: Fehler sollten immer korrekt behandelt und nicht ignoriert werden oder unbemerkt bleiben.
- 10. Es sei denn, sie sind ausdrücklich zum Schweigen gebracht: Es ist in Ordnung, Fehler zu ignorieren, wenn dies bewusst und explizit gemacht wird.
- 11. Angesichts der Mehrdeutigkeit weigere dich zu raten: Wenn etwas nicht klar ist, sollte der Code nicht versuchen zu erraten, was gemeint ist.
- 12. Es sollte eine – und vorzugsweise nur eine – offensichtliche Möglichkeit geben, es zu tun: Es ist besser, eine offensichtliche Art zu haben, Dinge zu tun, anstatt mehrere Möglichkeiten, die zu Verwirrung führen können.
- 13. Obwohl diese Möglichkeit nicht offensichtlich sein mag, es sei denn, man ist Holländer: Eine humorvolle Anspielung auf Guido van Rossum, den niederländischen Schöpfer von Python.
- 14. Jetzt ist besser als nie: Es ist besser, etwas zu tun, als es ständig aufzuschieben.
- 15. Obwohl „nie“ oft besser ist als jetzt gleich: Manchmal ist es jedoch besser, etwas nicht zu tun, vor allem, wenn es überstürzt und ohne genügend Nachdenken gemacht wird.
- 16. Wenn die Implementierung schwer zu erklären ist, ist es eine schlechte Idee: Ein guter Code sollte selbsterklärend sein.
- 17. Wenn die Implementierung leicht zu erklären ist, kann es eine gute Idee sein: Wenn eine Lösung einfach zu erklären ist, ist sie wahrscheinlich gut.
- 18. Namensräume sind eine großartige Idee – lassen Sie uns mehr davon machen: Namensräume helfen dabei, den Code sauber und organisiert zu halten, indem sie verhindern, dass Namen kollidieren.
Diese Prinzipien sind nicht strikt, aber sie bieten eine hilfreiche Anleitung, um einen Code zu schreiben, der lesbar, verständlich und leicht zu pflegen ist.
Im nächsten Teil unseres Blog-Beitrags werden wir uns Typisierung, Pydantic und weiteren wichtigen Best Practices für Data Engineering und AI widmen.