Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Code Style und Konventionen

Make your code consistent through style conventions. For interactive reading and executing code blocks Binder and find b08-pystyle.ipynb, or install Python and JupyterLab locally.

Atmen Sie tief durch, nehmen Sie ab und betrachten Sie, was Sie bisher aus einer neuen Perspektive gelernt haben. Nach diesem Kapitel lohnt es sich, einen weiteren Blick auf Ihren alten Code zu werfen und ihn robust zu formatieren. Die hier vorgestellten Stilrichtlinien gehen über die visuelle Ästhetik hinaus und helfen beim Schreiben von effektivem Code.

incubate to solve Python programming problems

Hintergrund und PEP

Dieser Styleguide hebt Teile des PEP 8 - Style Guide for Python Code] von Guido van Rossum, Barry Warsaw und Nick Coghlan hervor. Das vollständige Dokument ist verfügbar unter python.org] und nur Aspekte mit Relevanz für die in diesem eBook gezeigten Anwendungen werden in diesem Kapitel vorgestellt.

Was ist ein PEP? PEP steht für Python Enhancement Proposal. Ein PEP ist ein Entwurfsdokument, das Informationen für die Python-Community bereitstellt oder eine vorgeschlagene Funktion, einen vorgeschlagenen Prozess oder eine damit verbundene Änderung beschreibt. Es gibt viele PEPs, einschließlich Standard-Track-, Informations- und Prozessvorschläge. In diesem Kapitel werden die Empfehlungen von PEP 8, dem Styleguide für Python-Code, von Guido van Rossum, Barry Warsaw und Alyssa Coghlan hervorgehoben.

Viele IDEs, einschließlich PyCharm oder VS Code, bieten automatische Vervollständigung und Tooltips mit PEP-Style-Anleitung, um eine konsistente Programmierung zu unterstützen. Wenn Ihre IDE also etwas in Ihrem Skript unterstreicht, überprüfen Sie den Grund dafür und überlegen Sie, den Code entsprechend zu ändern.

Das Zen von Python

Werden wir spirituell? Ganz im Gegenteil. Das Zen von Python ist ein Informations PEP (20) von Tim Peters, um Programmierer zu führen.] Es sind ein paar Zeilen, die gute Praxis in der Codierung zusammenfassen. Pythons Easter Egg import this druckt das Zen von Python in jedem Python-Interpreter:

import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Codelayout

Maximale Streckenlänge

PEP 8 recommends limiting code lines to 79 characters. Flowing text in comments and docstrings should be limited to 72 characters. A team may agree on a code-line limit of up to 99 characters, provided that comments and docstrings remain limited to 72 characters.

Indentation

Indentation groups statements into suites controlled by constructs such as for, if, while, try, with, def, and class. PEP 8 recommends four spaces per indentation level. Indentation does not by itself create a new variable scope: names assigned in an if or for suite remain in the surrounding scope. Functions, classes, modules, and some comprehensions have their own scoping rules.

for i in range(1, 2):
  print("I'm one level indented.")
  if i == 1:
	  print("I'm two levels indented.")
I'm one level indented.
I'm two levels indented.

Da lange Codezeilen eine schlechte Praxis sind, müssen wir manchmal Zeilenumbrüche verwenden, wenn wir zum Beispiel eine * Liste * zuweisen oder eine Funktion aufrufen. In diesen Fällen wird auch die nächste, fortlaufende Linie eingerückt und es gibt verschiedene Möglichkeiten, mehrzeilige Zuweisungen einzurücken. Hier wollen wir den Stilcode der Verwendung eines öffnenden Trennzeichens für die Einrückung verwenden:

a_too_long_word_list = ["Do", "not", "hard-code", "something", "like", "this.",
                        "There", "are", "better", "ways."]
a_better_indented_list = [
    "Do",
    "not",
    "hard-code",
    "something",
    "like",
    "this.",
    "...",
    ]

**Recall: PyCharm, VS Code und viele andere IDEs Layout-Einrückung automatisch. **

Line Breaks von Ausdrücken mit binären Operatoren

Wenn binäre Operatoren Teil eines Ausdrucks sind, der die maximale Zeilenlänge von 79 Zeichen überschreitet, sollte der Zeilenumbruch vor den binären Operatoren liegen.

import pandas as pd

dummy_df = pd.get_dummies(
  pd.Series(["variable1", "parameter2", "sensor3"]),
  dtype=int,
)
print(dummy_df.head(3))

dum_sum = (
  dummy_df["variable1"]
  + dummy_df["parameter2"]
  - dummy_df["sensor3"]
)
   parameter2  sensor3  variable1
0           0        0          1
1           1        0          0
2           0        1          0

Leerlinien

Um Codeblöcke zu trennen, ist es eine sehr einladende Option, die Taste Enter viele Male zu drücken. Die zufällige und stimmungsgesteuerte Verwendung von leeren Linien führt jedoch zu unstrukturiertem Code. Aus diesem Grund bieten PEP 8 Autoren auch Hinweise zur Verwendung von leeren Linien:

  • Surround class definitions and top-level functions (i.e., functions where the def-line is not indented) with two blank lines.

  • Surround-Methoden (z. B. Funktionen innerhalb einer Klasse) mit einer leeren Linie.

  • Verwenden Sie leere Zeilen spärlich in allen anderen Codes, um logische Abschnitte anzuzeigen.

# blank 1 before top-level function
# blank 2 before top-level function
def top_level_function():
    pass
# blank 1 after top-level function
# blank 2 after top-level function

Rohlinge (Whitespaces)

Vermeiden Sie unnötige Leerzeichen unmittelbar in Klammern, Klammern oder Klammern; vor Kommas, Semikolonen und gewöhnlichen Doppelpunkten; oder zwischen einem Funktionsnamen und seiner Argumentliste. Schreiben Sie function(e1, e2), (1,), a_dict = {a_key: a_value} und def fun(arg=0.0):.

Verwenden Sie Leerzeichen rund um Zuordnung, Vergleich und boolesche Operatoren. Fügen Sie für arithmetische Ausdrücke Leerzeichen um die Operatoren mit der niedrigsten Präzedenz hinzu und verwenden Sie das Urteil, um die Priorität klarzustellen; zum Beispiel hypot2 = x*x + y*y.

Pakete und Module

Einfuhren

Importe erscheinen normalerweise nach dem Modul-Docstring und vor Modul-Globals. Gruppieren Sie sie in dieser Reihenfolge mit einer leeren Linie zwischen den Gruppen: Standardbibliothek, zugehörige Drittanbieterpakete und lokale Anwendungen oder Bibliotheksimporte. Legen Sie gewöhnliche Importe auf getrennte Linien und vermeiden Sie Wildcard-Importe. Jeder Import sollte eine eigene Zeile haben und vermeiden, das Kommazeichen für mehrere Importe zu verwenden:

import os
import sys

import numpy as np

from my_package import my_module

Naming Packages und Script

Neue, benutzerdefinierte Pakete oder Module sollten kurze und Kleinbuchstabennamen haben, wobei Unterstriche zur Verbesserung der Lesbarkeit verwendet werden können (entmutigt für Pakete).

Anmerkungen

Block und Inline Kommentare

Block comments are indented to the same level as the code they describe, and each line begins with # . Use inline comments sparingly. An inline comment appears on the same line as a statement, is separated from it by at least two spaces, and begins with # .

Zeichenketten

A docstring is a string literal that occurs as the first statement in a module, function, class, or method. It becomes available through the object’s __doc__ attribute. PEP 257 recommends triple double quotes. For example:

a_list = [1, 2]
print(a_list.__doc__)
Built-in mutable sequence.

If no argument is given, the constructor creates a new empty list.
The argument must be an iterable if specified.

When writing a Python function, docstrings are introduced immediately after the def ... line with triple double-quotes:

def let_there_be_light(*args, **kwargs):
  """Print a sunrise message and return `True`.

  Args:
	  *args: Positional arguments accepted but not used.
	  **kwargs: Keyword arguments accepted but not used.

  Returns:
	  `True` in all cases.
  """
  print("Sunrise")
  return True

print(let_there_be_light.__doc__)

    Bright function accepting any input argument with indifferent behavior.
    :param an_input_argument: STR or anything else
    :param another_input_argument: FLOAT or anything else
    :return: True (in all cases)
    

Beachten Sie, dass die Empfehlungen zu Docstrings mit PEP 257 statt PEP 8 versehen sind.

Bezeichnungsvereinbarungen

Definition von Namensstilen

Die Namenskonventionen verwenden die folgenden Stile (Quelle: python.org]):

  • Classes normally use CapWords, for example MyClass.

  • User-defined exception classes follow the class-naming convention and normally use the suffix Error when they represent an error, for example ConfigurationError.

  • Funktionen, Methoden und Variablen verwenden Kleinbuchstaben, die durch Unterstriche getrennt sind, wenn dies für die Lesbarkeit erforderlich ist.

  • Constants normally use uppercase words separated by underscores, for example WATER_DENSITY = 1000.

Einige Variablennamenformate lösen ein bestimmtes Verhalten von Python aus:

  • _single_leading_underscore variables indicate weak internal use and will not be imported with from module import *

  • __double_leading_underscore variables invoke name mangling in classes (e.g., a method called __dlu of the class MyClass will be mangled into _MyClass__dlu)

  • __double_leading_and_trailing_underscore__ Variablen sind magische Objekte oder Attribute in benutzergesteuerten Namensräumen (z. B. __init__ oder __call__ in Klassen)
    Verwenden Sie nur dokumentierte magische Attribute und erfinden Sie sie nie. Lesen Sie mehr über Zaubermethoden im Kapitel Python classes.

  • single_trailing_underscore_ variables are used to avoid conflicts with Python keywords (e.g., MyClass(class_='AnotherClass'))

Objektnamen

Verwenden Sie die oben definierten Stile, um Python-Elemente wie folgt zu benennen:

  • Klassen: CamelCase (CapWords) nur Buchstaben wie MyClass

  • Constants: UPPERCASE letters only, where underscores may improve readability (e.g., use at a module level for example to assign water density RHO = 1000)

  • Ausnahmen: CamelCase (CapWords) nur Buchstaben (Ausnahmen sollten vordefiniert sein Fehler Klassen; verwenden Sie normalerweise das Suffix Error (z. B. TypeError)

  • Funktionen: Nur lowercase Buchstaben, wobei Unterstriche die Lesbarkeit verbessern können; manchmal gilt mixedCase, um die Rückwärtskompatibilität der vorherrschenden Stile zu gewährleisten.

  • Methoden (Klassenfunktion, nicht-öffentlich): _lowercase Buchstaben nur mit einem führenden Unterstrich, wobei Unterstriche die Lesbarkeit verbessern können

  • Methoden (Klassenfunktion, öffentlich): lowercase nur Buchstaben, bei denen Unterstriche die Lesbarkeit verbessern können

  • Module: lowercase nur Buchstaben, in denen Unterstriche die Lesbarkeit verbessern können

  • Pakete: lowercase Briefe nur, wo Unterstriche entmutigt werden

  • Variables: lowercase letters only, where underscores may improve readability

  • Variables (global): lowercase letters only, where underscores may improve readability; note that “global” should limit to variable usage within one module only.

Mehr Code Style Empfehlungen

Um Codekompatibilität und Programmeffizienz zu gewährleisten, enthält der PEP 8 Style Guide weitere allgemeine Empfehlungen (lesen Sie mehr im Python docs]):

  • Prefer a def statement when creating a named function; do not assign a lambda expression directly to a name. A short lambda can be appropriate when passed directly as an argument, for example items.sort(key=lambda item: item.name).

  • When exceptions are expected, use try - except clauses (see the errors and exceptions section).

  • Stellen Sie sicher, dass Methoden und Funktionen Objekte konsistent zurückgeben, zum Beispiel:

import numpy as np


def a_function_with_return(x):
  if x > 0:
	  return np.sqrt(x)
  return np.nan

Learning Success Check-up

Machen Sie den Lernerfolgstest für dieses Jupyter-Notebook].