Zum Inhalt springen
≈ 1 minNeuPythonCode-Qualität

Best Practices für Python

Python-Code, der lesbar, typisiert und reproduzierbar ist – mit PEP 8, Type Hints, isolierten Umgebungen und automatisierten Tests.

In 30 Sekunden

  1. 01

    Stil nicht diskutieren, sondern automatisieren – ruff formatiert und lintet nach PEP 8.

  2. 02

    Type Hints und ein Type Checker finden Fehler, bevor der Code läuft.

  3. 03

    Jedes Projekt bekommt eine eigene Umgebung mit gepinnten Abhängigkeiten, z. B. per uv.

Die wichtigsten Regeln

PEP 8 automatisch

ruff format und ruff check --fix im Pre-Commit-Hook. snake_case für Funktionen, PascalCase für Klassen.

Type Hints überall

Signaturen typisieren, mit mypy oder pyright prüfen. Für Datenobjekte dataclass oder Pydantic statt dict.

Eigene Umgebung

Nie ins System-Python installieren. uv init, uv add requests – Lockfile committen.

Tests mit pytest

Einfache assert-Tests, Fixtures für Setup, pytest --cov für Abdeckung.

Ressourcen mit with

Dateien, Verbindungen und Locks per Context Manager – sie werden garantiert geschlossen.

logging statt print

Log-Level, Zeitstempel und Ziel sind konfigurierbar – print ist es nicht.

Klassiker: veränderliche Default-Argumente

Nicht so

def add_tag(tag, tags=[]):
    tags.append(tag)
    return tags

add_tag("a")  # ['a']
add_tag("b")  # ['a', 'b']  ← Überraschung

So

def add_tag(tag: str, tags: list[str] | None = None) -> list[str]:
    tags = [] if tags is None else tags
    tags.append(tag)
    return tags

Moderner Alltag

Alt

import os
f = open(os.path.join(base, "data.json"))
data = json.load(f)
print("Loaded " + str(len(data)))

Modern

from pathlib import Path
with (base / "data.json").open() as f:
    data = json.load(f)
log.info("Loaded %d records", len(data))

Merksatz

„Lesbar vor clever – Python belohnt explizite, einfache Lösungen.“

Selbsttest

Erst selbst überlegen, dann aufklappen.

01Warum ist `def add(item, items=[])` gefährlich?

Der Default-Wert wird nur einmal beim Definieren erzeugt – alle Aufrufe teilen sich dieselbe Liste. Besser `items=None` und in der Funktion eine neue Liste anlegen.

Weiter in Grundlagen

Best Practices für SQL