init at work

This commit is contained in:
Mathias Schneider
2026-03-27 12:58:01 +01:00
parent 352c352056
commit 8d40597732
60 changed files with 16498 additions and 0 deletions
+525
View File
@@ -0,0 +1,525 @@
Hier eine umfassende, aber für Einsteiger verständliche Einführung in **black**, den „opinionated“ Python-Code-Formatter.
---
## 1. Grundidee von *black*
**Was ist black?**
- *black* ist ein **automatisches Formatierungs-Tool** für Python.
- Es ändert **nur die Formatierung**, nicht die Logik deines Codes.
- Es ist **„opinionated“**: Es gibt nur sehr wenige Einstellungen black entscheidet den Stil für dich.
**Zentrale Idee:**
> „*You are not your code style.*“
> Statt darüber zu diskutieren, ob ein Leerzeichen hier oder dort besser ist, überlässt du das black.
>
> Ziel:
> - einheitlicher Stil
> - weniger Diskussionen in Code Reviews
> - Fokus auf inhaltliche Fehler, nicht auf Formatierung
---
## 2. Was macht black konkret?
Black nimmt deinen Python-Code, parst ihn und schreibt ihn nach festen Regeln neu. Beispiele:
### 2.1 Installation
```bash
pip install black
```
### 2.2 Einfache Nutzung
Eine einzelne Datei formatieren:
```bash
black main.py
```
Ein ganzes Projekt:
```bash
black .
```
Nur anzeigen, was geändert würde (ohne zu schreiben):
```bash
black --diff --check .
```
---
## 3. Praxisnahe Formatierungsbeispiele
### 3.1 Zeilenumbrüche und Einrückung
**Vorher:**
```python
def very_long_function_name(arg1,arg2,arg3,arg4,arg5,arg6,arg7=False,arg8=None):
return (arg1+arg2+arg3+arg4+arg5+arg6)
```
**Nachher (black):**
```python
def very_long_function_name(
arg1,
arg2,
arg3,
arg4,
arg5,
arg6,
arg7=False,
arg8=None,
):
return arg1 + arg2 + arg3 + arg4 + arg5 + arg6
```
Was passiert?
- Argumente werden sauber untereinander geschrieben.
- Operatoren (+) werden mit Leerzeichen versehen.
- Abschluss-Komma nach dem letzten Argument (hilft bei späteren Änderungen).
---
### 3.2 Strings und Anführungszeichen
Black bevorzugt fast immer **doppelte Anführungszeichen**.
**Vorher:**
```python
name = 'Alice'
message = 'Hello, ' + name + '!'
```
**Nachher:**
```python
name = "Alice"
message = "Hello, " + name + "!"
```
Ausnahmen:
- Wenn ein String doppelte Anführungszeichen enthält, kann black einzelne beibehalten, um weniger zu escapen.
---
### 3.3 Leerzeichen und Klammern
**Vorher:**
```python
result=(1+2)*3
if x==42:
print( 'Answer',x )
```
**Nachher:**
```python
result = (1 + 2) * 3
if x == 42:
print("Answer", x)
```
Black:
- fügt Leerzeichen um Operatoren hinzu (`1 + 2`, `x == 42`),
- entfernt unnötige Leerzeichen (`print( 'Answer',x )``print("Answer", x)`).
---
### 3.4 Collections (Listen, Dicts, Sets)
**Vorher:**
```python
config = {"host":"localhost","port":5432,"debug":True}
```
**Nachher:**
```python
config = {
"host": "localhost",
"port": 5432,
"debug": True,
}
```
Vorteile:
- Bessere Lesbarkeit
- Leicht, neue Einträge hinzuzufügen (wegen Abschluss-Komma).
---
### 3.5 Lange Ausdrücke
**Vorher:**
```python
query = session.query(User).filter(User.is_active==True, User.signup_date>=start_date, User.signup_date<=end_date).order_by(User.signup_date.desc())
```
**Nachher:**
```python
query = (
session.query(User)
.filter(
User.is_active == True,
User.signup_date >= start_date,
User.signup_date <= end_date,
)
.order_by(User.signup_date.desc())
)
```
Black bricht lange Zeilen so um, dass:
- sie unter der vorgegebenen Maximalbreite bleiben (standard: 88 Zeichen),
- die Struktur des Codes klarer sichtbar wird.
---
## 4. Abgrenzung zu verwandten Tools
### 4.1 Formatter vs. Linter vs. Typprüfer
- **Formatter** (Formatierer):
Passen das **Aussehen** deines Codes an z.B. black, autopep8, yapf.
- **Linter**:
Finden mögliche **Fehler, Stilprobleme oder unschöne Konstrukte** z.B. flake8, pylint, ruff.
- **Typprüfer**:
Prüfen, ob Typen konsistent sind (z.B. mit `typing`) z.B. mypy, pyright.
Black ist **nur** ein Formatter.
---
### 4.2 Black vs. autopep8
**autopep8**:
- Ziel: Code so anpassen, dass er PEP8-konform ist.
- Orientierung direkt an den PEP8-Regeln.
- Viele Optionen (z.B. bestimmte Checks an- oder abschalten).
**black**:
- Ziel: **konsequenter, einheitlicher Stil** nicht nur PEP8, sondern zusätzliche strenge Regeln.
- Sehr wenige Konfigurationsmöglichkeiten (bewusst!).
- Output ist oft deutlich „strenger” und einheitlicher als autopep8.
---
### 4.3 Black vs. yapf
**yapf**:
- Google-Tool zur Formatierung von Python.
- Sehr konfigurierbar: du kannst deinen Style stark beeinflussen (ähnlich wie bei C++/clang-format).
- Mehr Freiheit, aber dadurch auch mehr Diskussionen möglich.
**black**:
- „Meine Regeln oder gar nicht“.
- Ziel: Diskussionen vermeiden, daher kaum Konfigurationsoptionen.
- Sehr stabiler, vorhersehbarer Output.
---
### 4.4 Black vs. isort
**isort** ist ein Tool, um **Imports** zu sortieren und zu gruppieren.
- Sortiert `import`-Zeilen alphabetisch und nach Gruppen:
- Standardbibliothek
- Third-Party
- Projektinterne Module
Black:
- Formatiert auch Imports (Zeilenumbrüche, Leerzeichen),
- sortiert sie aber **nicht** nach Paketnamen.
Typischerweise nutzt man:
```bash
isort .
black .
```
Oder beides zusammen über Tools wie `ruff` oder `pre-commit`.
---
## 5. Welche Probleme löst black?
### 5.1 Konsistenter Stil in Teams
Ohne Tool:
- Jeder schreibt „sein“ Python.
- Unterschiedliche Leerzeichen, Umbrüche, String-Stile, etc.
- Code wirkt „bunt“ und uneinheitlich.
Mit black:
- Jedes Commit, jede Datei, jede Funktion hat denselben Stil.
- Neue Teammitglieder lernen schneller, was „üblich“ ist es ist einfach: das, was black macht.
---
### 5.2 Weniger Diskussionen in Code Reviews
Vor black:
- Kommentare wie: „Bitte hier ein Leerzeichen einfügen.“
- „Kannst du die Argumente untereinander schreiben?“
- „Wir verwenden eigentlich doppelte Anführungszeichen.“
Mit black:
- Reviewer sagen: „Bitte einmal black drüber laufen lassen.“
- Fokus liegt auf:
- Ist der Algorithmus korrekt?
- Sind die Funktionen gut benannt?
- Sind Tests vorhanden?
---
### 5.3 Bessere Lesbarkeit & Wartbarkeit
- Lange Zeilen werden sinnvoll umgebrochen.
- Verschachtelte Ausdrücke werden strukturiert.
- Datensammlungen (Listen, Dicts) werden mehrzeilig und übersichtlich dargestellt.
Beispiel: Eine unübersichtliche Dict-Liste wird automatisch gut lesbar formatiert.
**Vorher:**
```python
users=[{"id":1,"name":"Alice","active":True},{"id":2,"name":"Bob","active":False}]
```
**Nachher:**
```python
users = [
{"id": 1, "name": "Alice", "active": True},
{"id": 2, "name": "Bob", "active": False},
]
```
---
### 5.4 Weniger „Rauschen“ in Git-Diffs
Manuell Änderungen + Formatierung:
- Du änderst eine Zeile, formatierst etwas,
- der Diff zeigt viele Änderungen, obwohl nur wenig Logik geändert wurde.
Mit black:
- Wenn alle Dateien bereits formatiert sind, entstehen bei späteren Änderungen klarere Diffs:
- Format ist überall gleich,
- nur die wirklich geänderte Logik fällt auf.
---
## 6. Herausforderungen und typische Stolpersteine
### 6.1 Einstieg in ein bestehendes Projekt
Problem:
- Du führst black in einem **alten, großen Projekt** ein.
- Beim ersten Durchlauf ändert black Hunderte/tausende Dateien.
- Git-Diff ist riesig.
Lösungen / Best Practices:
- Einmaliger „Formatting-Commit“ (nur Style):
- In einem eigenen Commit alle Dateien mit black formatieren.
- Danach neue Commits nur mit funktionalen Anpassungen.
- Oder schrittweise:
- Nur neue/aktuell bearbeitete Module mit black formatieren.
- z.B. mit `pre-commit`-Hook nur geänderte Dateien behandeln.
---
### 6.2 „Mir gefällt der Stil nicht!“
Black ist sehr strikt:
- Du kannst nicht „mal eben“ sagen:
- „Ich möchte lieber 120 statt 88 Zeichen pro Zeile“ (ok, das **geht** als Option)
- Aber: Du kannst nicht festlegen, wie exakt bestimmte Konstrukte formatiert werden.
Beispiel: Viele stören sich zunächst an:
- doppelten Anführungszeichen,
- „ungewöhnlichen“ Zeilenumbrüchen.
Wichtig:
- black ist ein **Team-Tool**.
- Man einigt sich darauf, den Stil zu akzeptieren, um Diskussionen zu vermeiden.
---
### 6.3 Integration mit anderen Tools (z.B. isort, flake8, ruff)
Typische Stolperfallen:
- `isort` und `black` können sich widersprechen, wenn sie unterschiedliche Maximalzeilenlängen nutzen.
- Linter können sich über Formatierung beschweren, wenn sie anders konfiguriert sind als black.
Best Practice:
- Einheitliche Konfiguration, z.B. in `pyproject.toml`:
```toml
[tool.black]
line-length = 88
[tool.isort]
profile = "black"
line_length = 88
```
So passen Formatierung und Importsortierung zusammen.
---
### 6.4 Änderungen zwischen Black-Versionen
Black entwickelt sich weiter.
- In seltenen Fällen ändert eine neue Version den Stil leicht.
- Dann kann ein erneuter Durchlauf große Diffs erzeugen.
Abhilfe:
- Black-Version in `pyproject.toml` oder `requirements.txt` fest pinnen:
```text
black==24.4.2
```
- Gelegentlich bewusst aktualisieren und einmaliger Reformatting-Commit.
---
### 6.5 Performance bei sehr großen Projekten
Für normale Projekte ist black schnell genug.
Bei **sehr großen Repositories** kann einmaliges Formatieren aber dauern.
Lösungen:
- Nur geänderte Dateien formatieren (z.B. über `pre-commit`).
- In CI nur `black --check .` laufen lassen (prüft, ob alles formatiert ist, ohne neu zu schreiben).
---
## 7. Black in der Praxis: Workflows
### 7.1 Integration in den Editor/IDE
Die meisten Editoren können black beim Speichern ausführen:
- **VS Code**:
- Erweiterung „Python“ installieren.
- In `settings.json`:
```json
{
"python.formatting.provider": "black",
"editor.formatOnSave": true
}
```
- **PyCharm**:
- Externes Tool konfigurieren oder über Plugins.
Vorteil:
- Du denkst nicht mehr über Formatierung nach: Speichern = fertig formatiert.
---
### 7.2 Verwendung mit `pre-commit`
`pre-commit` ist ein Tool, das Skripte ausführt, bevor ein Git-Commit akzeptiert wird.
Installieren:
```bash
pip install pre-commit
```
In `.pre-commit-config.yaml`:
```yaml
repos:
- repo: https://github.com/psf/black
rev: 24.4.2 # Version anpassen
hooks:
- id: black
```
Aktivieren:
```bash
pre-commit install
```
Jetzt wird bei jedem `git commit` black auf die geänderten Dateien angewandt.
Das stellt sicher, dass alles im Repo immer formatiert ist.
---
### 7.3 Black in der CI-Pipeline
In CI-Systemen (GitHub Actions, GitLab CI, etc.) kannst du prüfen, ob der Code schon formatiert ist.
Beispiel (CLI):
```bash
black --check .
```
- Exit-Code 0: alles ok.
- Exit-Code ≠ 0: irgendetwas müsste formatiert werden.
Das verhindert, dass unformatierter Code in `main` oder `master` landet.
---
## 8. Zusammenfassung
- **black** ist ein **sehr strenger, kaum konfigurierbarer Formatter** für Python-Code.
- Ziel:
- **einheitlicher Stil**,
- **keine Diskussionen** über Formatierung,
- Fokus auf Logik und Qualität statt auf Leerzeichen.
- Abgrenzung:
- black formatiert nur es ist kein Linter und kein Typprüfer.
- Im Vergleich zu autopep8/yapf: weniger konfigurierbar, dafür klarer, einheitlicher Stil.
- Es löst:
- Stil-Inkonsistenz, Formatierungs-Diskussionen, „Rauschen“ in Diffs.
- Herausforderungen:
- Einstieg in ältere Projekte,
- wenig Einfluss auf Stil,
- Abstimmung mit anderen Tools, Versionsänderungen.
- In der Praxis:
- Nutze black im Editor (Format-on-save),
- im `pre-commit`-Hook,
- und als `--check` in der CI.
Wenn du möchtest, kann ich dir im nächsten Schritt ein kleines Beispielprojekt konstruieren (mit `pyproject.toml`, `pre-commit`, isort/black-Konfiguration), damit du siehst, wie man black von Anfang an sauber einrichtet.