Heim >Backend-Entwicklung >Python-Tutorial >Schritte zum Organisieren und Verwalten Ihrer Python-Codebasis für Anfänger
Der Grund, warum ich diesen Beitrag schreibe, besteht darin, einige Erkenntnisse darüber zu teilen, wie man ein Projekt auch mit vielen Mitwirkenden sauber hält. Dies ist besonders wichtig für Dateningenieure, da sich die Art der Daten und die Verarbeitungsanforderungen in Python-Bibliotheken und -Anwendungen ständig ändern.
Der Titel klingt vielleicht ein wenig nach Clickbait, aber wenn Sie diese Schritte befolgen, wird Ihr Python-Code viel einfacher zu verwalten sein. Wenn Sie ein erfahrener Entwickler sind, werden Sie hier wahrscheinlich nichts Neues finden – keine Sorge, ich habe ein lustiges Meme für Sie.
Das mag trivial erscheinen, aber ich kenne tatsächlich Leute, die ihren Code nur auf ihren lokalen Computern gespeichert haben – und ihn leider verloren haben, weil sie ihn nirgendwo anders gesichert haben. Es stehen mehrere Versionskontrollsysteme zur Verfügung, beispielsweise Git, das mit Plattformen wie GitHub, GitLab und Bitbucket funktioniert. Während Git für viele die erste Wahl ist, spielen andere Versionskontrollsysteme wie SVN (Subversion) und Mercurial immer noch eine wichtige Rolle bei der Codeverwaltung.
Für diesen Leitfaden möchte ich eine kleine Demo-Python-Bibliothek mit einer einzigen Funktion erstellen, um die grundlegende Datenverarbeitung zu veranschaulichen. Es ist nicht als vollständiges Toolkit gedacht, sondern dient als einfaches Beispiel für die Demonstration von Best Practices wie Codequalität, Umgebungsmanagement und CI/CD-Workflows.
Um zu beginnen, habe ich ein Repository für unsere Demo-Python-Bibliothek erstellt und es blog_de_toolkit genannt. Es ist öffentlich, Sie können es also gerne teilen und den vorhandenen Code als Ausgangspunkt für Ihre eigenen Projekte verwenden. Da eine gute Dokumentation unerlässlich ist, habe ich eine empfohlene leere README-Datei beigefügt. Und um das Repo aufgeräumt zu halten, habe ich eine Standard-Python-Gitignore-Vorlage hinzugefügt, um zu verhindern, dass unnötige Dateien hochgeladen werden.
Jetzt, da wir das Repo haben, können wir es klonen.
Ich werde hier nicht näher auf Git-Befehle eingehen – online finden Sie zahlreiche Tutorials. Wenn Sie kein Fan der einfachen Terminal-CLI sind, können Sie Repositorys auch mit Tools wie GitHub Desktop oder SourceTree verwalten, die eine visuellere, intuitivere Benutzeroberfläche bieten.
Ich persönlich verwende GitHub Desktop sehr gerne. Klonen wir also unser Repo auf den lokalen Computer und öffnen es in Ihrer bevorzugten IDE.
Mal sehen, was wir bisher haben:
Für den Anfang nicht schlecht!
Für Schritt 2 organisieren wir unser de_toolkit-Projekt. Eine gute Struktur erleichtert das Auffinden von Dingen und sorgt für Ordnung. Wir erstellen Ordner für unseren Code, unsere Tests und unsere Dokumentation und richten ein einfaches, sauberes Framework ein, auf dem wir aufbauen können.
blog_de_toolkit/ │ ├── de_toolkit/ │ ├── __init__.py │ └── data_tools.py │ ├── tests/ │ ├── __init__.py │ └── test_data_tools.py │ ├── .gitignore ├── setup.py └── README.md
Wir haben einen Hauptordner für den gesamten nützlichen Code, den wir hinzufügen werden, einen Ordner Tests für unsere zukünftigen Komponententests und eine .gitignore-Datei, um unnötige Dateien aus unserem Repository fernzuhalten. Es gibt auch eine setup.py-Datei, die ein grundlegendes Setup darstellt, um das Projekt installierbar zu machen. Ich werde jetzt nicht näher darauf eingehen, da wir später in Schritt 8: Erstellen eines Verteilungspakets darauf eingehen.
Beim Einrichten Ihrer Projektstruktur macht es einen großen Unterschied, die Dinge konsistent zu halten. Wenn Ihr Projekt wächst, ist es eine gute Idee, die Dinge in kleinere Module aufzuteilen – wie etwa die Aufteilung von data_tools.py in csv_tools.py und json_tools.py. Auf diese Weise ist es einfacher, das Gesuchte zu verwalten und zu finden, ohne lange Dateien durchwühlen zu müssen.
Das Hinzufügen eines Ordners docs/ ist ebenfalls ein kluger Schachzug, selbst wenn es nur mit ein paar Notizen beginnt. Es wird Ihnen (und anderen) helfen, den Überblick darüber zu behalten, wie die Dinge funktionieren, während sich das Projekt weiterentwickelt. Wenn Sie mit Konfigurationen wie YAML oder JSON arbeiten, kann ein Ordner configs/ für Ordnung sorgen. Und wenn Sie planen, Skripts für die Automatisierung oder zum Testen zu schreiben, sorgt ein Ordner scripts/ für die Organisation.
Zu diesem Zeitpunkt müssen wir einige zusätzliche Bibliotheken installieren, um den Aufbau des Projekts fortzusetzen.
Klar, wir könnten einfach pip install über die Befehlszeile ausführen, um die benötigten Abhängigkeiten zu installieren. Was aber, wenn wir mit mehreren Projekten jonglieren, die jeweils unterschiedliche Versionen von Python und Bibliotheken erfordern? Hier kommen virtuelle Umgebungen ins Spiel – sie isolieren die Abhängigkeiten jedes Projekts, einschließlich bestimmter Python-Versionen, sodass alles in sich geschlossen und unabhängig bleibt.
Glücklicherweise gibt es eine ganze Reihe von Tools zum Erstellen virtueller Umgebungen, sodass Sie auswählen können, was für Sie am besten funktioniert:
virtualenv
venv
conda
pyenv
pipenv
Poesie
Ich persönlich bin ein großer Fan von pyenv, deshalb werde ich es hier verwenden. Ich habe es bereits auf meinem Laptop installiert, da es meine erste Wahl für die Arbeit und private Projekte ist.
Beginnen wir mit der Installation von Python:
blog_de_toolkit/ │ ├── de_toolkit/ │ ├── __init__.py │ └── data_tools.py │ ├── tests/ │ ├── __init__.py │ └── test_data_tools.py │ ├── .gitignore ├── setup.py └── README.md
Wenn pyenv diese Python-Version nicht erkennt, versuchen Sie zunächst, sie zu aktualisieren. Wenn Sie beispielsweise einen Mac verwenden und pyenv mit Homebrew installiert haben, führen Sie Folgendes aus:
pyenv install 3.12.2
Wenn der Fehler ModuleNotFoundError: Kein Modul namens „_lzma“ auftritt, versuchen Sie Folgendes:
brew update && brew upgrade pyenv
Als nächstes erstellen wir in unserem Projektordner eine neue virtuelle Umgebung:
brew install readline xz
Stellen Sie nun die lokale Python-Version auf die virtuelle Umgebung ein, die Sie gerade erstellt haben:
pyenv virtualenv 3.12.2 de_toolkit
Wenn sich die Umgebung nach der Ausführung des Befehls unter MacOS nicht ändert, gibt es online einen hilfreichen Thread mit einer Lösung. Sobald alles richtig eingerichtet ist, sollte de_toolkit am Anfang Ihrer Befehlszeile angezeigt werden, etwa so:
Jetzt installieren wir unsere Abhängigkeiten:
pyenv local de_toolkit
Als nächstes speichern wir alle installierten Pakete zusammen mit ihren Versionen in einer Datei „requirements.txt“. Dies macht es einfach, die Abhängigkeiten des Projekts zu teilen oder dieselbe Umgebung an anderer Stelle neu zu erstellen:
pip install setuptools wheel twine pandas
Hier ist die Liste der installierten Pakete, die wir erhalten haben:
Natürlich können Sie die Datei „requirements.txt“ bearbeiten, um nur die Hauptbibliotheken und ihre Versionen beizubehalten, wenn Sie möchten.
Dieser Schritt ist entscheidend – wahrscheinlich einer der wichtigsten. Sie haben wahrscheinlich Horrorgeschichten über die Offenlegung von Anmeldeinformationen in GitHub-Repositories oder über vertrauliche Token gehört, die versehentlich öffentlich geteilt wurden. Um dies zu vermeiden, ist es wichtig, sensible Informationen von Anfang an aus Ihrem Code fernzuhalten. Andernfalls vergisst man leicht, dass Sie ein Datenbankkennwort fest codiert haben, pushen Ihre Änderungen und boomen – Ihre Anmeldeinformationen sind jetzt öffentlich.
Das Festkodieren von Passwörtern, API-Schlüsseln oder Datenbankanmeldeinformationen stellt ein großes Sicherheitsrisiko dar. Wenn diese in ein öffentliches Repo gelangen, könnten sie Ihr gesamtes System gefährden. Der sicherste Weg, mit Geheimnissen umzugehen, besteht darin, sie in Umgebungsvariablen oder einer .env-Datei zu speichern. Um das Laden dieser Variablen in Ihr Python-Projekt zu erleichtern, verwenden wir die Bibliothek python-dotenv. Es liest Schlüssel-Wert-Paare aus einer .env-Datei und stellt sie als Umgebungsvariablen in Ihrem Code zur Verfügung.
Installieren Sie zunächst die Bibliothek mit:
pip freeze > requirements.txt
Erstellen Sie eine .env-Datei in Ihrem Projektordner mit folgendem Inhalt:
pip install python-dotenv
Jetzt ändern wir data_tools.py, um diese Geheimnisse mit python-dotenv:
zu ladenWenn Sie load_dotenv() aufrufen, sucht es im aktuellen Verzeichnis nach einer .env-Datei und lädt deren Inhalt in die Umgebung. Durch die Verwendung von os.getenv() können Sie in Ihrem Code sicher auf diese Variablen zugreifen, wodurch Anmeldeinformationen vom Quellcode isoliert bleiben und das Risiko einer versehentlichen Offenlegung verringert wird.
Ein wichtiger Tipp ist, Ihre .env-Datei nicht der Versionskontrolle zu unterwerfen. Fügen Sie es zu .gitignore hinzu, um zu verhindern, dass es versehentlich gepusht wird:
blog_de_toolkit/ │ ├── de_toolkit/ │ ├── __init__.py │ └── data_tools.py │ ├── tests/ │ ├── __init__.py │ └── test_data_tools.py │ ├── .gitignore ├── setup.py └── README.md
Wenn Sie VSCode verwenden, gibt es eine hilfreiche Dotenv-Erweiterung, die Ihre .env *Dateien automatisch erkennt. Und wenn Sie lieber vom Terminal aus arbeiten möchten, können Sie die *.env-Datei wie folgt exportieren:
pyenv install 3.12.2
Versuchen Sie bei der Arbeit an Ihrem Projekt, kleine, wiederverwendbare Funktionen zu schreiben, die leicht zu verstehen und zu verwalten sind. Eine gute Faustregel lautet: „Wenn Sie es mehr als zweimal verwenden, verwandeln Sie es in eine Funktion.“
Lassen Sie uns in unserem data_tools.py eine Funktion erstellen, die typische Data-Engineering-Logik demonstriert – etwa das Laden von Daten aus einer CSV-Datei und deren Bereinigung:
Profi-Tipp: Halten Sie sich für Funktions- und Variablennamen in Python an snake_case
– so bleibt Ihr Code konsistent und leicht lesbar. Vermeiden Sie kryptische Namen wie x oder df2; Klare, beschreibende Namen erleichtern die Arbeit mit Ihrem Code.Wir verwenden hier Dokumentzeichenfolgen, um zu beschreiben, was die Funktion tut, ihre Parameter und den Rückgabetyp. Dies macht es für andere Entwickler (und Sie selbst) einfacher zu verstehen, wie die Funktion verwendet wird. Es gibt mehrere beliebte Docstring-Konventionen, aber die gebräuchlichsten sind PEP 257, Google Style und NumPy Style:
Für kleinere Funktionen reicht oft PEP 257 aus, aber für komplexere Projekte bieten Google- oder NumPy-Stile mehr Klarheit und Struktur.
Typhinweise in Python, wie etwa „file_path: str“ in unserem Beispiel, zeigen die erwarteten Datentypen für Funktionseingänge und -ausgaben. Sie verbessern die Lesbarkeit, helfen beim Erkennen von Fehlern und erleichtern die Zusammenarbeit, indem sie klare Erwartungen festlegen.
Hier ist ein Beispiel dafür, wie Typhinweise die Funktionssignatur verbessern:
blog_de_toolkit/ │ ├── de_toolkit/ │ ├── __init__.py │ └── data_tools.py │ ├── tests/ │ ├── __init__.py │ └── test_data_tools.py │ ├── .gitignore ├── setup.py └── README.md
In diesem Beispiel zeigt der Typhinweis file_path: str, dass das Argument eine Zeichenfolge sein sollte, während -> pd.DataFrame gibt an, dass die Funktion einen Pandas DataFrame zurückgibt. Dadurch ist das Verhalten der Funktion auf einen Blick leicht verständlich. Typhinweise funktionieren auch gut mit IDEs und Linters wie PyCharm, VSCode oder mypy und bieten automatische Vervollständigung und Frühwarnungen, wenn inkompatible Typen übergeben werden.
Wenn eine Funktion mehrere Typen oder Keine zurückgeben kann, können Sie Optional aus dem Typisierungsmodul verwenden:
pyenv install 3.12.2
Dies zeigt an, dass die Funktion entweder eine Zeichenfolge oder „Keine“ zurückgeben könnte. Für komplexere Datenstrukturen können Sie List, Dict oder Tuple aus dem Typisierungsmodul verwenden, um erwartete Typen anzugeben.
Das Schreiben von Unit-Tests ist eine einfache Möglichkeit, um sicherzustellen, dass Ihr Code das tut, was er soll, ohne unerwartete Überraschungen. Sie helfen Ihnen, Fehler frühzeitig zu erkennen und Änderungen mit Zuversicht vorzunehmen, mit der Gewissheit, dass alles immer noch wie erwartet funktioniert. In Python stehen mehrere Bibliotheken für Unit-Tests zur Verfügung, jede mit ihren Stärken und ihrem Ökosystem:
unittest
pytest
Nase2
Hypothese
Für diesen Leitfaden verwenden wir pytest, weil es einfach, flexibel und benutzerfreundlich ist. Sie können es installieren mit:
brew update && brew upgrade pyenv
Als nächstes erstellen Sie eine Datei mit dem Namen test_data_tools.py im Ordner tests/. Schreiben wir einige Tests für den Code, den wir zuvor implementiert haben. Hier ist ein Beispieltest für unsere Funktion „load_and_clean_data()“ und die Logik zum Abrufen von Umgebungsvariablen:
In test_load_and_clean_data() verwenden wir StringIO, um eine CSV-Datei als Eingabe zu simulieren. Dadurch können wir testen, ohne eine tatsächliche Datei zu benötigen. Der Test überprüft, ob die Funktion Duplikate und NaN-Werte korrekt entfernt, prüft, ob im DataFrame keine fehlenden Daten vorhanden sind und bestätigt, dass die eindeutigen Einträge in der Spalte „Name“ korrekt sind.
In test_get_database_url() und test_get_api_key() verwenden wir monkeypatch, ein von pytest bereitgestelltes Dienstprogramm, um Umgebungsvariablen während des Tests vorübergehend festzulegen. Dadurch wird sichergestellt, dass die Funktionen die erwarteten Werte zurückgeben, ohne dass echte Umgebungsvariablen erforderlich sind.
Um alle Tests auszuführen, führen Sie einfach den folgenden Befehl aus:
blog_de_toolkit/ │ ├── de_toolkit/ │ ├── __init__.py │ └── data_tools.py │ ├── tests/ │ ├── __init__.py │ └── test_data_tools.py │ ├── .gitignore ├── setup.py └── README.md
Einer der Gründe, warum ich pytest liebe, ist seine Flexibilität. Es geht über grundlegende Unit-Tests hinaus und bietet leistungsstarke Funktionen wie Fixtures, parametrisierte Tests und Plugins. Mit Fixtures können Sie Testdaten oder Konfigurationen einrichten, die von mehreren Tests wiederverwendet werden können, wodurch Ihr Code trocken bleibt (Don’t Repeat Yourself). Mit parametrisierten Tests können Sie denselben Test mit unterschiedlichen Eingaben ausführen, was Zeit spart und Doppelarbeit reduziert. Und wenn Sie die Funktionalität von Pytest erweitern müssen, gibt es ein breites Ökosystem an Plugins für Dinge wie das Testen von Django-Apps, das Messen der Codeabdeckung oder das Verspotten von HTTP-Anfragen.
Durch die Aufrechterhaltung einer hohen Codequalität wird sichergestellt, dass Ihr Code leicht zu lesen, zu warten und frei von häufigen Fehlern ist. Mehrere Tools können dabei helfen, konsistente Codierungsstandards durchzusetzen, Code automatisch zu formatieren und potenzielle Probleme frühzeitig zu erkennen. Zu den beliebten Optionen gehören pylint, flake8, black und detect-secrets.
pylint setzt Codierungsstandards durch und erkennt häufige Fehler.
flake8 kombiniert Tools zur Erkennung von Stilverstößen und logischen Fehlern.
black ist ein eigenwilliger Formatierer, der sicherstellt, dass Ihr Code den PEP8-Standards entspricht.
detect-secrets scannt Ihren Code, um zu verhindern, dass hartcodierte Geheimnisse preisgegeben werden.
Sie können diese Tools installieren mit:
pyenv install 3.12.2
Führen Sie beispielsweise Pylint für eine bestimmte Datei oder ein bestimmtes Verzeichnis aus:
brew update && brew upgrade pyenv
Sie erhalten einen Bericht mit Warnungen und Vorschlägen zur Verbesserung Ihres Codes. Um bestimmte Warnungen zu ignorieren, können Sie Folgendes verwenden:
brew install readline xz
Sie können flake8 auch verwenden, um Stilprobleme und logische Fehler zu finden:
blog_de_toolkit/ │ ├── de_toolkit/ │ ├── __init__.py │ └── data_tools.py │ ├── tests/ │ ├── __init__.py │ └── test_data_tools.py │ ├── .gitignore ├── setup.py └── README.md
Um Ihren Code automatisch zu formatieren, führen Sie black:
auspyenv install 3.12.2
Anstatt diese Tools jedes Mal manuell auszuführen, wenn Sie Änderungen vornehmen, können Sie den Prozess mit Pre-Commit-Hooks automatisieren. Pre-Commit-Hooks werden automatisch vor jedem Commit ausgeführt und blockieren den Commit, wenn ein Tool fehlschlägt.
Installieren Sie zunächst das Pre-Commit-Paket:
brew update && brew upgrade pyenv
Als nächstes erstellen Sie eine .pre-commit-config.yaml-Datei in Ihrem Projektverzeichnis mit folgendem Inhalt (hier habe ich alle meine bevorzugten grundlegenden Pre-Commits verwendet):
Aktivieren Sie die Pre-Commit-Hooks in Ihrem lokalen Repository:
blog_de_toolkit/ │ ├── de_toolkit/ │ ├── __init__.py │ └── data_tools.py │ ├── tests/ │ ├── __init__.py │ └── test_data_tools.py │ ├── .gitignore ├── setup.py └── README.md
Jetzt werden diese Tools bei jedem Commit-Versuch automatisch ausgeführt. Wenn ein Tool fehlschlägt, wird der Commit blockiert, bis das Problem behoben ist. Sie können alle Hooks auch manuell in Ihrer Codebasis ausführen:
pyenv install 3.12.2
Nachdem wir nun unser Projekt erstellt, Code geschrieben, Tests hinzugefügt und Pre-Commit-Hooks eingerichtet haben, besteht der nächste Schritt darin, herauszufinden, wie andere (oder sogar wir zukünftige) es einfach verwenden können. Die Verpackung des Projekts macht dies möglich. Dadurch können wir alles ordentlich bündeln, sodass es installiert und verwendet werden kann, ohne Dateien manuell kopieren zu müssen.
Um Ihr Projekt zu teilen, müssen Sie das Paket richtig strukturieren, eine aussagekräftige README-Datei schreiben, ein Startskript erstellen und das Verteilungspaket generieren. Eine gute README-Datei enthält normalerweise den Projektnamen und eine kurze Beschreibung dessen, was es tut, Installationsanweisungen, Anwendungsbeispiele, Entwicklungsanweisungen zum Einrichten der Umgebung und Richtlinien für die Mitarbeit. Ein einfaches README.md-Beispiel für unser blog_de_toolkit-Projekt finden Sie im Repository.
Das Herzstück jedes Python-Pakets ist die Datei setup.py. In dieser Datei definieren wir die Metadaten und die Konfiguration, die zum Packen und Installieren unseres Projekts erforderlich sind. Es enthält den Namen, die Version und die Beschreibung des Projekts, die es identifizierbar machen. Die long_description liest aus der README-Datei, um Benutzern mehr Kontext zum Projekt zu geben, wenn sie es auf PyPI sehen. Wir geben Abhängigkeiten in der install_requires-Liste an, damit sie automatisch zusammen mit dem Paket installiert werden. Der Abschnitt entry_points definiert einen Eintrag für die Befehlszeilenschnittstelle (CLI), sodass Benutzer das Tool von ihrem Terminal aus ausführen können. Wir verwenden find_packages(), um alle Submodule in das Paket einzuschließen, und der Abschnitt classifiers stellt Metadaten bereit, z. B. welche Python-Version und Lizenz das Projekt verwendet. Schließlich stellt das Feld „python_requires“ sicher, dass das Paket nur auf kompatiblen Python-Versionen installiert wird. Hier ist die setup.py-Konfiguration für unser blog_de_toolkit-Projekt:
Sobald setup.py konfiguriert ist, können Sie das Distributionspaket erstellen. Beginnen Sie mit der Installation der erforderlichen Tools mit:
blog_de_toolkit/ │ ├── de_toolkit/ │ ├── __init__.py │ └── data_tools.py │ ├── tests/ │ ├── __init__.py │ └── test_data_tools.py │ ├── .gitignore ├── setup.py └── README.md
Dann erstellen Sie das Paket:
pyenv install 3.12.2
Dieser Befehl erstellt zwei Distributionsdateien:
sdist: Ein Quellarchiv (z. B. .tar.gz)
bdist_wheel: Ein erstelltes Paket (z. B. .whl)
Diese Dateien befinden sich im Verzeichnis dist/. Um das Paket zu testen, installieren Sie es lokal mit:
brew update && brew upgrade pyenv
Sie können den CLI-Befehl auch testen, indem Sie Folgendes ausführen:
brew install readline xz
Hier sollten die Datenbank-URL, der API-Schlüssel und die bereinigten Daten aus sample_data.csvausgedruckt werden.
Wenn Sie das Paket öffentlich teilen möchten, können Sie es auf PyPI hochladen. Installieren Sie zunächst Twine:
pyenv virtualenv 3.12.2 de_toolkit
Dann laden Sie das Paket hoch:
pyenv local de_toolkit
Sie werden aufgefordert, Ihre PyPI-Anmeldeinformationen einzugeben. Nach dem Hochladen können andere Ihr Paket direkt von PyPI aus installieren mit:
pip install setuptools wheel twine pandas
Wenn Ihr Projekt wächst, arbeiten mehr Leute oft gleichzeitig an derselben Codebasis. Ohne angemessene Sicherheitsvorkehrungen ist es leicht, dass sich Fehler, ungetesteter Code oder versehentliche Zusammenführungen einschleichen und die Dinge durcheinander bringen. Um einen reibungslosen Ablauf zu gewährleisten und hohe Standards aufrechtzuerhalten, ist der Schutz der Hauptniederlassung unerlässlich. In diesem Schritt schauen wir uns an, wie man Branch-Schutzregeln einrichtet und geben einige Tipps für die Durchführung reibungsloser Codeüberprüfungen bei Pull-Requests.
Zweigschutzregeln stellen sicher, dass niemand direkt zum Hauptzweig pushen kann, ohne Tests zu bestehen oder eine Codeüberprüfung zu erhalten. Dies verhindert, dass sich unvollendete Funktionen, Fehler oder fehlerhafter Code einschleichen und das Projekt zerstören. Es fördert auch die Teamarbeit, indem es Pull-Anfragen erfordert und anderen die Möglichkeit gibt, Feedback zu geben. Darüber hinaus stellen automatisierte Prüfungen – wie Tests und Linters – sicher, dass der Code vor dem Zusammenführen solide ist.
Das Einrichten von Zweigschutzregeln auf GitHub ist ziemlich einfach. Gehen Sie zu den Einstellungen Ihres Repositorys und klicken Sie im Abschnitt „Code und Automatisierung“ auf Zweige. Suchen Sie nach Zweigstellenschutzregeln und klicken Sie auf Zweigstellenschutzregel hinzufügen. Geben Sie main in das Zweignamensfeld ein, und jetzt ist es an der Zeit, einige Einstellungen zu optimieren.
Sie können Branch-Schutzregeln so festlegen, dass Pull-Request-Überprüfungen erforderlich sind, um sicherzustellen, dass jemand den Code überprüft, bevor er zusammengeführt wird. Statusprüfungen stellen sicher, dass die Tests erfolgreich sind und Linters reibungslos funktionieren. Wenn Sie die Zweige über die neuesten Änderungen auf dem Laufenden halten, können Sie Konflikte vermeiden. Bei Bedarf können Sie einschränken, wer in den Zweig pushen darf, oder für zusätzliche Sicherheit sogar signierte Commits verlangen. Sobald alles eingerichtet ist, klicken Sie auf Erstellen und schon geht es los – keine direkten Pushs oder übersprungenen Tests mehr.
Wenn Ihre Pull-Anfrage zur Überprüfung ansteht, ist es eine gute Idee, Ihren Prüfern die Arbeit zu erleichtern. Beginnen Sie mit einer klaren Beschreibung dessen, was Ihre Änderungen bewirken und warum sie erforderlich sind. Verwenden Sie aussagekräftige Commit-Nachrichten, die widerspiegeln, was aktualisiert wurde. Wenn die Änderungen klein und gezielt sind, verläuft der Überprüfungsprozess reibungsloser und schneller. Vergessen Sie nicht, höflich auf Kommentare zu antworten und gewünschte Änderungen nachzuverfolgen – das zeigt, dass Sie Feedback wertschätzen und trägt dazu bei, dass die Zusammenarbeit positiv bleibt.
Wenn Sie eine Pull-Anfrage überprüfen, geht Ihre Aufgabe über das bloße Finden von Fehlern hinaus – es geht darum, den Code zu verbessern und Ihren Teamkollegen zu unterstützen. Lesen Sie zunächst die Pull-Request-Beschreibung, um zu verstehen, was mit den Änderungen erreicht werden soll. Konzentrieren Sie sich darauf, konstruktives Feedback zu geben – schlagen Sie bei Bedarf Alternativen vor und erklären Sie, warum diese möglicherweise besser funktionieren. Gute Arbeit mit einem einfachen „Netter Refactor?!“ anerkennen trägt auch dazu bei, ein positives Bewertungserlebnis zu schaffen. Behalten Sie die Prüfungen im Auge, um sicherzustellen, dass sie vorhanden, relevant und bestanden sind. Und wenn etwas nicht klar ist, stellen Sie Fragen, anstatt Annahmen zu treffen. Letztendlich geht es bei Bewertungen um Teamarbeit – darum, zusammenzuarbeiten, um das Projekt gemeinsam besser zu machen.
Die Verwendung von Bewertungsvorlagen kann dazu beitragen, den Prozess reibungsloser zu gestalten, da sich alle auf das Wesentliche konzentrieren können. Hier ist ein Beispiel für eine Pull-Request-Überprüfungsvorlage:
blog_de_toolkit/ │ ├── de_toolkit/ │ ├── __init__.py │ └── data_tools.py │ ├── tests/ │ ├── __init__.py │ └── test_data_tools.py │ ├── .gitignore ├── setup.py └── README.md
Das Hinzufügen einer Vorlage wie dieser zu Ihren Beitragsrichtlinien oder die Verknüpfung im Repository erleichtert es den Prüfern, den Überblick zu behalten. Es sorgt außerdem dafür, dass die Dinge bei allen Überprüfungen konsistent bleiben, und hilft dem Team, eine saubere und organisierte Codebasis aufrechtzuerhalten.
Aufgrund der Wichtigkeit, Ihren Hauptzweig zu schützen, ist es auch wichtig, sicherzustellen, dass jede Codeänderung ordnungsgemäß getestet, überprüft und validiert wird, bevor sie zusammengeführt oder bereitgestellt wird. Hier kommen Continuous Integration (CI) und Continuous Delivery/Deployment (CD) ins Spiel. CI/CD automatisiert den Prozess der Durchführung von Tests, der Durchführung von Codeprüfungen und der Bereitstellung von Änderungen, bietet Entwicklern schnelles Feedback und verringert die Wahrscheinlichkeit, dass Fehler in die Produktion gelangen.
GitHub Actions ist ein Automatisierungstool, das direkt in GitHub integriert ist. Sie können damit Workflows erstellen, die auf Ereignisse in Ihrem Repository reagieren, beispielsweise Push- oder Pull-Anfragen. In GitHub Actions können wir mehrere wichtige Aufgaben automatisieren, um eine gesunde Codebasis aufrechtzuerhalten. Zum Beispiel:
Tests immer dann ausführen, wenn Code gepusht oder eine Pull-Anfrage erstellt wird, um sicherzustellen, dass neue Änderungen nichts kaputt machen.
Überprüfen des Codestils und des Lintings, um konsistente Codierungsstandards durchzusetzen.
Anwenden von Pre-Commit-Hooks, um den Code zu formatieren und kleine Probleme wie nachgestellte Leerzeichen zu erkennen.
Dokumentation erstellen oder sogar den Code bereitstellen, wenn alle Prüfungen erfolgreich sind.
Lassen Sie uns einen GitHub Actions-Workflow einrichten, der unsere Unit-Tests ausführt und Pre-Commit-Linters (wie Black) anwendet, wann immer eine Push- oder Pull-Anfrage im Hauptzweig erfolgt.
Erstellen Sie zunächst die Workflow-Datei:
blog_de_toolkit/ │ ├── de_toolkit/ │ ├── __init__.py │ └── data_tools.py │ ├── tests/ │ ├── __init__.py │ └── test_data_tools.py │ ├── .gitignore ├── setup.py └── README.md
Hier ist der Inhalt für ci.yml:
Dieser Workflow automatisiert das Testen und Linting, wann immer Code gepusht oder eine Pull-Anfrage im Hauptzweig geöffnet wird. Es stellt sicher, dass alle Qualitätsprüfungen bestanden werden, bevor der Code zusammengeführt wird. Die Aktion „actions/checkout“ klont das Repository in den Runner, und wir verwenden „actions/setup-python“, um Python 3.12 für den Workflow zu konfigurieren. Abhängigkeiten werden mithilfe von pip aus „requirements.txt“ installiert. Danach werden alle Tests mit pytest ausgeführt und Pre-Commit-Hooks stellen sicher, dass der Code den Formatierungs- und Stilrichtlinien entspricht. Wenn ein Test oder eine Prüfung fehlschlägt, wird der Workflow angehalten, um zu verhindern, dass fehlerhafter Code zusammengeführt wird.
Lass es uns testen. Erstellen Sie zunächst einen neuen Hauptzweig und nehmen Sie einige Änderungen vor.
In meinem Fall habe ich die Datei README aktualisiert. Übernehmen Sie Ihre Änderungen und öffnen Sie eine Pull-Anfrage im Hauptzweig.
Jetzt sehen Sie, dass die Überprüfung erforderlich ist und GitHub Actions (GA) alle Prüfungen durchführt. Auch wenn das Zusammenführen durch Zweigschutzregeln blockiert ist, kann ich trotzdem „Zusammenführen, ohne auf die Erfüllung der Anforderungen zu warten“, da meine Berechtigungen das Umgehen der Schutzmaßnahmen zulassen.
Sie können die Ergebnisse Ihres GitHub-Aktionsworkflows auf der Registerkarte Aktionen verfolgen.
Hier ist ein Beispiel dafür, wie der Pytest-Schritt während eines Laufs aussieht:
Die manuelle Verfolgung der Version Ihres Projekts kann schwierig werden, insbesondere wenn es wächst. Hier kommt die semantische Versionierung (SemVer) ins Spiel – sie folgt dem MAJOR.MINOR.PATCH-Muster, um zu kommunizieren, was sich in jeder Version geändert hat. Die Automatisierung der Versionierung mit python-semantic-release macht dies noch einfacher. Es analysiert Ihre Commit-Nachrichten, aktualisiert die Version basierend auf der Art der Änderungen, markiert Veröffentlichungen und kann Ihr Paket bei Bedarf sogar auf PyPI veröffentlichen. Dies macht das Rätselraten bei der Versionsverwaltung überflüssig und sorgt für Konsistenz.
Für eine nahtlose Versionierung können Sie python-semantic-release direkt in GitHub Actions integrieren. Die offizielle Dokumentation stellt Arbeitsabläufe bereit, die Versionswechsel und Veröffentlichungen automatisieren, wann immer Sie in den Hauptzweig pushen. Mit diesem Setup verläuft der Veröffentlichungsprozess reibungslos und unkompliziert, sodass Sie sich auf das Schreiben von Code konzentrieren können, ohne sich Gedanken über die manuelle Verwaltung von Versionen machen zu müssen.
Gemeinsames Workflow-Beispiel – python-semantic-release
Damit dies funktioniert, müssen Ihre Commit-Nachrichten herkömmlichen Commit-Standards entsprechen. Jeder Commit-Typ bestimmt, ob die Version die Stufe PATCH, MINOR oder MAJOR erreicht:
Fix: Löst eine PATCH-Versionserhöhung aus (z. B. 1.0.0 → 1.0.1).
feat: Löst eine kleine Versionserhöhung aus (z. B. 1.0.0 → 1.1.0).
BREAKING CHANGE: oder ! in der Commit-Nachricht löst einen GROSSEN Versionssprung aus (z. B. 1.0.0 → 2.0.0).
Wenn Sie diese einfachen Konventionen befolgen, wissen Sie immer, was Sie mit jeder neuen Version erwartet.
Wir haben alles abgedeckt, von der Organisation Ihres Projekts und der Verwaltung von Geheimnissen bis hin zum Schreiben von Tests, der Automatisierung von Arbeitsabläufen und der Handhabung von Releases mit semantischer Versionierung. Mit den richtigen Tools und Prozessen wird der Aufbau eines zuverlässigen und wartbaren Projekts viel reibungsloser – und macht sogar Spaß.
Der Schlüssel liegt darin, konsistent zu bleiben, zu automatisieren, wo Sie können, und sich im Laufe der Zeit weiter zu verbessern. Jeder kleine Schritt macht im Laufe der Zeit einen großen Unterschied. Jetzt sind Sie an der Reihe – bauen Sie, experimentieren Sie und genießen Sie den Prozess! Versuchen Sie, diese Schritte auf Ihr nächstes Projekt anzuwenden – und teilen Sie Ihre Erfahrungen gerne in den Kommentaren!
Das obige ist der detaillierte Inhalt vonSchritte zum Organisieren und Verwalten Ihrer Python-Codebasis für Anfänger. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!