init at work
This commit is contained in:
Executable
+525
@@ -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.
|
||||
Reference in New Issue
Block a user