Make your code consistent through style conventions. For interactive reading and executing code blocks and find b08-pystyle.ipynb, or install Python and JupyterLab locally.
Watch this section as a video
Watch this section as a video on the @Hydro-Morphodynamics channel on YouTube.
Atmen Sie tief ein, nehmen Sie aus und schauen Sie sich an, 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 Style-Richtlinien gehen über visuelle Ästhetik und Hilfe beim Schreiben effektiver Code.

Hintergrund und PEP¶
Dieser Stilführer zeigt Teile des PEP 8 - Style Guide for Python Code von Guido van Rossum, Barry Warsaw und Nick Coghlan. Das vollständige Dokument ist unter python.org erhältlich und in diesem Kapitel sind nur Aspekte mit Relevanz für die in diesem eBook gezeigten Anwendungen aufgeführt.
Was ist PEP? PEP steht für Python Enhancement **Proposals*, in denen Python-Entwickler Funktionen und Entwicklungen von Python kommunizieren. Es gibt mehrere tausend PEPs, die die vorgeschlagenen Sprachmerkmale, Bugfix-Releases, Prozesse und Style-Guide abdecken (lesen Sie die vollständige und aktuelle Liste der PEPs unter python.org). Dieser Abschnitt enthält Empfehlungen, die in PEP 8, dem Stilführer für Python-Code angegeben sind.
Viele IDEs, einschließlich PyCharm oder VS-Code, bieten Auto-Vervollständigung und Tooltips mit PEP-Stil Anleitung, um konsequente Programmierung zu unterstützen. So, wenn Ihre IDE unterstreicht alles in Ihrem Skript, überprüfen Sie den Grund dafür und prüfen, den Code entsprechend zu ändern.
Das Zen von Python¶
Werden wir spirituell? Weit davon. Das Zen von Python ist ein Informationsblatt PEP (20) von Tim Peters, um Programmierer zu leiten. Es ist ein paar Linien, die gute Praxis bei der Codierung zusammenfassen. Python’s Easter Egg import this druckt das Zen von Python in jedem Python Dolmetscher:
import thisThe 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!
Code Layout¶
Maximale Linienlänge¶
Die maximale Länge einer Zeile beträgt 79 Zeichen und Inline-Kommentare, einschließlich docstrings, sollten 72 Zeichen nicht überschreiten.
Identifizierung¶
Indentation bezeichnet die Verschiebung von Code (Blocks) nach rechts. Eine Eindrückung ist beispielsweise in Schleifen oder Funktionen erforderlich, um Codeblöcke einer for oder def-Anweisung zuzuordnen. Im weiteren Sinne stellen Einbuchtungen Namensräume dar, in denen lokale Variablen, die im eingezeichneten Bereich definiert sind, nur hier gültig sind. Bei Verwendung von verschachtelten Aussagen treten mehrere Einbuchtungen auf (z.B. eine if-Zustand in einer for-Schleife). Eine Einbuchtung entspricht 4 Räumen.
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.
Weil lange Zeilen von Code schlechte Praxis sind, müssen wir manchmal Zeilenumbrüche verwenden, wenn wir beispielsweise eine list zuweisen oder eine Funktion anrufen. In diesen Fällen wird auch die nächste, weiterführende Linie eingerückt und es gibt verschiedene Optionen, um Multi-Line-Beträge zu identifizieren. Hier möchten wir den Stilcode der Verwendung eines Öffnungsbegrenzers für die Einbuchtung 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 automatisch Layout-Einbuchtung.
Line Breaks of Expressions mit binären Operatoren¶
Wenn binäre Operatoren Teil eines Ausdrucks sind, der die maximale Zeilenlänge von 79 Zeichen überschreitet, sollte der Zeilenbruch vor den binären Operatoren sein.
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
Leere Linien¶
Um Code-Blöcke zu trennen, schlagen Sie den Enter Schlüssel oft ist eine sehr einladende Option. Die zufällige und stimmungsgesteuerte Verwendung von leeren Linien führt jedoch zu unstrukturiertem Code. Deshalb bieten PEP 8 Autoren auch Hinweise auf die Verwendung von Leerzeilen:
Surround-Klassendefinitionen und Top-Level-Funktionen (d.h. Funktionen, bei denen die
def-line nicht eingezeichnet ist) mit zwei Leerzeilen.Umgebungsmethoden (z.B. Funktionen innerhalb einer Klasse) mit einer leeren Linie.
Verwenden Sie leere Zeilen sparsam in allen anderen Code, 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 functionLeere (Weißräume)¶
Whitespaces helfen, das Code-Layout zu entspannen, aber zu viele whitespaces sollten vermieden werden wie zum Beispiel:
In Klammern, Klammern oder Klammern (Nr.:
list( e1, e2 )vs. ja:list(e1, e2))In Klammern mit nachlaufenden Kommas (Nr.:
a_tuple = (1, )vs. ja:a_tuple = (1,))Sofort vor einem Komma
Zwischen Funktionsname und Argumentparenthesen (Nr.:
fun (arg)vs. ja:fun(arg)) und ähnlich für Listen- oder WörterbuchelementeUm das
=-Zeichen unbemerkter Funktionsparameter, die einen Standardwert angeben (Nr.:def fun(arg = 0.0)vs. ja:def fun(arg=0.0))Vor
:, es sei denn, Klammern oder Klammern folgen der:(z.B.a_dict = {a_key: a_value})
*Whitespaces sollten hinzugefügt werden:
Um jeden Betreiber, Boolean oder (begehrte) Zuweisung (z.B.
==, <, >, !=, <=, >=, in, not in, is, is not, and, or, not, +=, -=)Nach Kolonen
:, wenn ein Wert die:anerkennt und keine Klammern oder Klammern unmittelbar nach der:(z.B.a_dict = {a_key: a_value})
Pakete und Module¶
Einfuhr¶
Die Importe sind an der Spitze des Skripts, direkt nach docstrings oder anderen Modulkommentaren. Importieren Sie zunächst Bibliotheken, dann Pakete von Drittanbietern und zuletzt lokal gespeicherte (eigene) Module. Vorzugsweise verwenden Sie absolute Importe (z.B. import package.module oder from package import module) und vermeiden Sie Wildcard-Importe (from module import *). Jeder Import sollte eine eigene Linie haben und die Verwendung des Kommazeichens für mehrere Importe vermeiden:
# DO:
import os
import numpy as np
# DO NOT:
import os, sysNamenspakete und Skript¶
Neue, benutzerdefinierte Pakete oder Module sollten kurze und All-Lowercase-Namen haben, wo Unterpunkte verwendet werden können, um die Lesbarkeit zu verbessern (für Pakete entmutigt).
Bemerkungen¶
Block und Inline Kommentare¶
Blockkommentare beginnen mit einer einzigen # an der ersten Stelle einer Zeile, gefolgt von einem Whitespace und dem Kommentartext.
Inline-Kommentare folgen einem Ausdruck und werden mit zwei Whitespaces eingezeichnet. Inline-Kommentare sollten jedoch sparsam verwendet werden.
Ärzte¶
Docstrings sind kurze Textbeschreibungen innerhalb eines Moduls, einer Funktion, einer Klasse oder einer Methode mit Argumenten, Verwendung und Ausgabe. Wenn das __doc__-Attribut ein Standardobjekt oder eine Klassenmethode anzeigt, werden die docstring-Informationen des Objekts gedruckt. Zum Beispiel:
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.
Beim Schreiben einer Python-Funktion werden die Docstrings unmittelbar nach der def ...-Linie mit dreifachen Doppelapostrophen eingeführt:
def let_there_be_light(*args, **kwargs):
"""
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)
"""
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 anstatt PEP 8.
Bezeichnung Konventionen¶
Definition von Name Styles¶
Die Namenskonventionen verwenden die folgenden Stile (Quelle: python.org):
b(Einzelbrief)B(Einzelbrief)lowercaselower_case_with_underscoresUPPERCASEUPPER_CASE_WITH_UNDERSCORESCamelCaseorCapWordsorCapitalizedWordsorStudlyCaps.
Note: When using acronyms inCapWords, capitalize all the letters of the acronym (e.g.,HTTPResponseis better thanHttpResponse).mixedCase(Differen vonCapitalizedWordsper initialer Kleinbuchstabe!)Capitalized_Words_With_Underscores(abgeschrieben)
Einige variable Namensformate lösen ein bestimmtes Verhalten von Python aus:
_single_leading_underscoreVariablen geben einen schwachen internen Gebrauch an und werden nicht mitfrom module import *__double_leading_underscoreVariablen rufen den Namen mangling in den Klassen an (z.B. eine Methode namens__dluder KlasseMyClasswird in_MyClass__dlueingebunden)__double_leading_and_trailing_underscore__Variablen sind magic Objekte oder Attribute in benutzergesteuerten Namespaces (z.B.__init__oder__call__in Klassen)
Verwenden Sie nur dokumentierte magische Attribute und erfinden sie nie. Lesen Sie mehr über magische Methoden im Kapitel unter Python classes.single_trailing_underscore_Variablen werden verwendet, um Konflikte mit Python Keywords zu vermeiden (z.B.MyClass(class_='AnotherClass'))
Objektbezeichnungen¶
Verwenden Sie die oben definierten Stile für die Benennung von Python-Elementen wie folgt:
Klassen:
CamelCase(CapWords) nur Buchstaben wieMyClassKonstanten: Nur
UPPERCASEBuchstaben, bei denen Unterstriche die Lesbarkeit verbessern können (z.B. auf Modulebene verwenden, um WasserdichteRHO = 1000) zuzuweisen.Ausnahmen:
CamelCase(CapWords) Buchstaben nur (Ausnahmen sollten vordefiniert Error-Kurse sein; typischerweise verwenden Sie die suffixError(z.B.TypeError)Funktionen: Nur
lowercaseBuchstaben, bei denen Unterpunkte die Lesbarkeit verbessern können; manchmal giltmixedCase, um eine rückständige Kompatibilität der vorherrschenden Stile sicherzustellenMethoden (Klassenfunktion, nichtöffentlich):
_lowercaseBuchstaben nur mit einem führenden Unterpunkt, wo Unterpunkte die Lesbarkeit verbessern könnenMethoden (Klassenfunktion, öffentlich): Nur
lowercaseBuchstaben, bei denen Unterpunkte die Lesbarkeit verbessern könnenModule: Nur
lowercaseBuchstaben, wo Unterpunkte die Lesbarkeit verbessern könnenPakete: Nur
lowercaseBuchstaben, bei denen Unterstriche entmutigt werdenVariablen: Nur
lowercaseBuchstaben, wo Unterpunkte die Lesbarkeit verbessern könnenVariablen (global): Nur
lowercaseBuchstaben, bei denen Unterpunkte die Lesbarkeit verbessern können; beachten Sie, dass “global” nur innerhalb eines Moduls auf eine variable Nutzung beschränken sollte.
Mehr Code Style Empfehlungen¶
Um die Code-Kompatibilität und Programmeffizienz zu gewährleisten, bietet der PEP 8 Style Guide weitere allgemeine Empfehlungen (weitere Informationen in der Python docs):
Bei der Definition einer Funktion bevorzugen
def-Anweisungen überlambda-Ausdrücke, die nur für einmalige Nutzung sinnvoll sindWenn Ausnahmen erwartet werden, verwenden Sie
try-exceptKlauseln (siehe Abschnitt errors and exceptions)Stellen Sie sicher, dass Methoden und Funktionen Objekte konsequent zurückgeben, zum Beispiel:
def a_function_with_return(x):
if x > 0:
return np.sqrt(x)
else:
return np.nan