Zum Inhalt springen

Eintrag 008

PEP 8 in Python: die Stilregeln, die Einsteiger brauchen

Thema
Python
Veröffentlicht
Lesezeit
9 Min.
Getestet mit
Python 3.14.4, Ruff 0.17.0 (VS Code)

PEP 8 ist der offizielle Stil-Leitfaden für Python-Code. Er legt fest, wie du einrückst, Namen schreibst, Imports ordnest und lange Zeilen umbrichst. Python führt deinen Code auch ohne PEP 8 aus, aber mit PEP 8 sieht er so aus, wie andere Python-Entwickler es erwarten.

Was ist PEP 8?

Eine PEP (Python Enhancement Proposal) ist ein offizielles Dokument, in dem Regeln und Neuerungen für Python festgehalten werden. PEP 8 (öffnet in neuem Tab) gibt es seit 2001, geschrieben haben ihn Guido van Rossum, Barry Warsaw und Alyssa Coghlan. Der Grundgedanke steht gleich am Anfang: Code wird viel öfter gelesen als geschrieben.

Damit ist PEP 8 die praktische Seite vom Zen of Python. Das Zen sagt „Readability counts“, PEP 8 sagt, wie das im Code konkret aussieht. Und PEP 8 sagt auch, wann du eine Regel brechen darfst: wenn der Code dadurch schlechter zu lesen wäre oder der Rest deines Projekts es anders macht.

PEP 8 ist lang. Für den Anfang reichen fünf Bereiche: Einrückung, Namen, Imports, Zeilenlänge und Leerzeichen.

Einrückung: vier Leerzeichen

PEP 8 will vier Leerzeichen pro Ebene und keine Tabs. Tabs und Leerzeichen gemischt erlaubt Python gar nicht, dann bricht das Programm mit einem TabError ab.

Ich habe die Tab-Taste überall so eingestellt, dass sie vier Leerzeichen breit einrückt. In Python setzt VS Code dabei echte Leerzeichen ein. Das steht unten rechts in der Statusleiste als „Leerzeichen: 4“ (englisch „Spaces: 4“). Mit einem Klick darauf kannst du es ändern.

Namen: snake_case für fast alles

Variablen und Funktionen schreibst du klein, mehrere Wörter verbindest du mit Unterstrichen. Das nennt man snake_case, und so schreibe ich generell. Für Klassen und Konstanten gibt es eigene Schreibweisen:

WasSchreibweiseBeispiel
Variable, Funktionsnake_casespieler_name, punkte_berechnen()
KlasseCapWordsSpieler, HighscoreListe
KonstanteGROSSBUCHSTABENMAX_LEBEN
Modul (Dateiname)kurz und kleinspiel.py, highscore.py

In einem kleinen Spiel sieht das so aus:

Code 01 · Python
MAX_LEBEN = 3


class Spieler:
    def __init__(self, name):
        self.name = name
        self.leben = MAX_LEBEN


def punkte_berechnen(treffer, bonus=0):
    return treffer * 10 + bonus


held = Spieler("Mia")
print(held.name, held.leben, punkte_berechnen(3, bonus=5))
Ausgabe
Mia 3 35

Schon an der Schreibweise siehst du, was was ist: Spieler ist eine Klasse, MAX_LEBEN ändert sich nicht, punkte_berechnen ist eine Funktion. Die einbuchstabigen Namen l, O und I sollst du laut PEP 8 nie benutzen, weil man sie mit 1 und 0 verwechselt.

Imports: oben und gruppiert

Imports stehen ganz oben in der Datei, jeder in einer eigenen Zeile. PEP 8 teilt sie in drei Gruppen, mit einer Leerzeile dazwischen: erst die Standardbibliothek, dann installierte Pakete, dann deine eigenen Module.

Code 02 · Python
import os
import random

import pygame

import highscore

os und random gehören zu Python, pygame kommt von PyPI, highscore ist eine eigene Datei im Projekt. Innerhalb einer Gruppe sortiert man alphabetisch. Genau hier meldet sich bei mir am häufigsten Ruff, zum Beispiel wenn zwei Imports in einer Zeile stehen (import sys, os) oder die Reihenfolge nicht stimmt.

Zeilenlänge: 79 Zeichen

PEP 8 begrenzt eine Zeile auf 79 Zeichen, Kommentare und Docstrings auf 72. Teams dürfen sich auf bis zu 99 Zeichen einigen. In VS Code habe ich mir bei 79 Zeichen eine senkrechte Linie einblenden lassen. Mich daran zu halten, ist manchmal gar nicht leicht.

Am besten brichst du lange Zeilen innerhalb von Klammern um. Python liest alles bis zur schließenden Klammer als eine Zeile:

Code 03 · Python
spieler_name = "Mia"
punkte = 120
level = 4

meldung = (
    f"{spieler_name} hat {punkte} Punkte "
    f"und ist jetzt in Level {level}."
)
print(meldung)
Ausgabe
Mia hat 120 Punkte und ist jetzt in Level 4.

Zwei Strings, die direkt hintereinanderstehen, setzt Python von selbst zusammen. Das Leerzeichen am Ende von „Punkte “ ist deshalb wichtig. Wie die f-Strings darin funktionieren, steht in einem eigenen Beitrag.

Leerzeichen und Leerzeilen

Am Beispiel sind diese Regeln schneller erklärt. So sieht Code aus, der dagegen verstößt:

Code 04 · Python
def Punkte_Berechnen(Treffer,Bonus=0):
  ergebnis=Treffer*10+Bonus
  return ergebnis
class spieler:
    pass
print(Punkte_Berechnen(3,  Bonus = 5))

Er läuft, ist aber unruhig zu lesen. So sieht er nach PEP 8 aus:

Code 05 · Python
def punkte_berechnen(treffer, bonus=0):
    ergebnis = treffer * 10 + bonus
    return ergebnis


class Spieler:
    pass


print(punkte_berechnen(3, bonus=5))
Ausgabe
35
  • Um = bei einer Zuweisung und um Rechenzeichen steht je ein Leerzeichen: ergebnis = treffer * 10.
  • Bei Standardwerten und Schlüsselwort-Argumenten steht kein Leerzeichen um =: bonus=0, bonus=5.
  • Nach einem Komma kommt ein Leerzeichen, vor der schließenden Klammer keins.
  • Funktionen und Klassen auf oberster Ebene trennst du mit zwei Leerzeilen, Methoden in einer Klasse mit einer.

PEP 8 automatisch prüfen mit Ruff in VS Code

Das alles beim Schreiben im Kopf zu behalten, ist viel. Dafür gibt es Linter, also Programme, die deinen Code lesen und melden, was gegen die Regeln verstößt. Ich nutze Ruff (öffnet in neuem Tab) als Erweiterung in VS Code. Ruff ist Linter und Formatierer in einem: Es meldet Fehler und kann den Code auch selbst umbauen.

Warum ich VS Code nutze und was es für den Anfang sonst gibt, steht im Beitrag Python IDE für Anfänger.

VS Code mit der Datei test.py: die Zeilen import sys, os und import random sind unterstrichen, unten im Fenster Probleme stehen vier Meldungen von Ruff, I001 Import block is un-sorted or un-formatted und dreimal F401 imported but unused
Abb. 01 Ruff meldet unsortierte und unbenutzte Imports

Im Fenster „Probleme“ (englisch „Problems“, Cmd+Shift+M auf dem Mac, Strg+Shift+M unter Windows) steht hinter jeder Meldung, woher sie kommt, hier „Ruff“ mit der Nummer der Regel. Die Meldungen direkt in der Codezeile zeigt bei mir zusätzlich die Erweiterung Error Lens.

In meinem Lernprojekt habe ich bewusst eingestellt, dass Ruff Fehler nur anzeigt und nichts automatisch ändert. Den sauberen Stil will ich selbst lernen. Dafür liegt im Projekt eine Datei .vscode/settings.json:

Code 06 · JSON
{
    "[python]": {
        "editor.defaultFormatter": "charliermarsh.ruff",
        "editor.formatOnSave": false,
        "editor.rulers": [79]
    }
}

editor.rulers blendet die Linie bei 79 Zeichen ein. Setzt du editor.formatOnSave auf true, formatiert Ruff die Datei bei jedem Speichern. Von Hand geht das über die Befehlspalette (Cmd+Shift+P) mit „Dokument formatieren“ (englisch „Format Document“). Unsortierte und unbenutzte Imports räumt der Befehl „Ruff: Fix all auto-fixable problems“ auf, den gibt es nur auf Englisch.

Mit beiden Befehlen sieht die Datei von oben so aus:

VS Code mit derselben Datei test.py nach Ruff: keine Imports mehr, die Funktion Punkte_Berechnen mit vier Leerzeichen eingerückt, Leerzeichen um = und *, je zwei Leerzeilen vor class spieler und vor print, unten im Fenster Probleme der Satz „Im Arbeitsbereich wurden keine Probleme erkannt.“
Abb. 02 Nach Fix all und Dokument formatieren

Die Imports sind ganz verschwunden, weil die Datei sie gar nicht benutzt. Einrückung, Leerzeichen und Leerzeilen stimmen jetzt, und im Fenster „Probleme“ ist nichts mehr übrig. Die falschen Namen Punkte_Berechnen, Treffer und spieler stehen aber noch da.

Das liegt daran, dass Ruff zwei Dinge ohne Einstellung nicht prüft: die Länge der Zeilen und die Schreibweise der Namen. Beides schaltest du in einer pyproject.toml im Projektordner dazu, die Erweiterung liest sie mit:

Code 07 · TOML
[tool.ruff]
line-length = 79

[tool.ruff.lint]
extend-select = ["E", "W", "N"]

E und W sind Stilregeln aus PEP 8, darunter die Zeilenlänge, N sind die Namensregeln. Danach meldet Ruff auch Punkte_Berechnen und spieler. Ändern musst du die Namen selbst, das macht kein Formatierer für dich. Alle Regeln stehen in der Ruff-Doku zu den Regeln (öffnet in neuem Tab).

Nicht jede Unterstreichung kommt von Ruff. Weist du einer Variable mit : int später eine Kommazahl zu, ist das keine Stilfrage, sondern eine Typprüfung. Die macht in VS Code Pylance, und im Fenster „Probleme“ steht dann auch „Pylance“ dahinter.

Gilt PEP 8 auch für GDScript?

Nicht direkt, Godot hat einen eigenen Style Guide für GDScript (öffnet in neuem Tab). Vieles ist gleich: Variablen und Funktionen in snake_case, Klassen in PascalCase (wie CapWords), Konstanten in Großbuchstaben. Der größte Unterschied ist die Einrückung, GDScript will Tabs statt Leerzeichen.

Ich rücke in Godot auch mit der Tab-Taste ein, im Editor ist das bei mir ein Tab mit der Breite von vier Leerzeichen. Damit sieht es aus wie in Python und hält sich trotzdem an den Style Guide. Wie sich GDScript sonst von Python unterscheidet, steht in meinem Beitrag GDScript lernen.

Häufige Fragen

Ist PEP 8 Pflicht?

Nein. Python führt Code auch aus, wenn er sich nicht an PEP 8 hält. PEP 8 ist ein Leitfaden, an den sich die meisten Python-Projekte halten, damit sich fremder Code vertraut liest. PEP 8 sagt selbst, dass Einheitlichkeit im eigenen Projekt wichtiger ist als jede einzelne Regel.

Was ist der Unterschied zwischen Linter und Formatierer?

Ein Linter prüft deinen Code und meldet, was gegen Regeln verstößt, zum Beispiel unsortierte Imports oder falsche Namen. Ein Formatierer ändert den Code selbst, etwa Einrückung, Leerzeichen und Leerzeilen. Ruff kann beides.

Heißt es PEP 8 oder PEP8?

Beides ist gemeint. Offiziell heißt das Dokument PEP 8, mit Leerzeichen. PEP steht für Python Enhancement Proposal, die 8 ist die Nummer.

Weitere Beiträge findest du unter Python für Anfänger.

Hat dir der Beitrag geholfen?

Fehler gefunden oder eine Frage zum Code? Schreib einen Kommentar oder eine E-Mail.

Kommentare

Du brauchst kein Konto. Name und E-Mail sind freiwillig, die E-Mail-Adresse wird nicht angezeigt. Ich lese jeden Kommentar, bevor er erscheint. Mehr dazu im Datenschutz.

Mehr zu Python