Das ist die Fortführung des ersten Posts über PEP 8.

Diesmal geht es ausschließlich um einen generellen Designvorschlag, um ein gut geschriebenes Programm veröffentlichen zu können.

Im Kontext von PEP 8, ist dieser Beitrag unter Design for Inheritance zu finden.

Ab jetzt werden die Posts im Allgemeinen kürzer, damit man diese leichter verarbeiten kann.

Entscheidet immer, ob die Methoden und Instanzvariablen einer Klasse (zusammenfassend: „Attribute“) öffentlich oder nicht öffentlich sein sollen. Im Zweifelsfall wählt man non-public; es ist einfacher, es später öffentlich zu machen, als ein öffentliches Attribut non-public zu machen.

Öffentliche Attribute sind diejenigen, von denen man erwartet, dass sie von unabhängigen Clients der Klasse verwendet werden, mit der Verpflichtung, inkompatible Änderungen rückwärts zu vermeiden. Nicht-öffentliche Attribute sind solche, die nicht für die Verwendung durch Dritte bestimmt sind; Sie übernehmen keine Garantie dafür, dass nicht-öffentliche Attribute nicht verändert oder gar entfernt werden.

Wir verwenden hier nicht den Begriff „privat“, da in Python kein Attribut wirklich privat ist (ohne erhöhten Arbeitsaufwand).

Eine weitere Kategorie von Attributen sind diejenigen, die Teil der „Subklassen-API“ sind (in anderen Sprachen oft als „geschützt“ bezeichnet). Einige Klassen sind so konzipiert, dass sie vererbt werden können, um Aspekte des Verhaltens der Klasse zu erweitern oder zu modifizieren. Beim Design einer solchen Klasse ist darauf zu achten, dass explizit entschieden wird, welche Attribute öffentlich sind, die Teil der Unterklassen-API sind und wirklich nur von Ihrer Basisklasse verwendet werden dürfen.

In diesem Sinne sind hier die pythonischen Richtlinien:

  • Öffentliche Attribute sollten keine führenden Unterstriche enthalten.
  • Wenn der öffentliche Attributname mit einem reservierten Schlüsselwort kollidiert, hänge einen einzelnen nachlaufenden Unterstrich an deinen Attributnamen an. Dies ist einer Abkürzung oder fehlerhaften Schreibweise vorzuziehen. (Ungeachtet dieser Regel ist „cls“ jedoch die bevorzugte Schreibweise für jede Variable oder jedes Argument, von dem bekannt ist, dass es sich um eine Klasse handelt, insbesondere für das erste Argument einer Klassenmethode.)
  • Für einfache öffentliche Datenattribute ist es am besten, nur den Attributnamen ohne komplizierte Accessor/Mutator-Methoden zu verwenden. Denke daran, dass Python einen einfachen Weg zur zukünftigen Verbesserung bietet, falls du feststellst, dass ein einfaches Datenattribut benötigt wird, um das Funktionsverhalten zu verbessern. In diesem Fall solltest du Eigenschaften verwenden, um die funktionale Implementierung hinter einer einfachen Syntax für den Zugriff auf Datenattribute zu verstecken.
    • Hinweis 1: Eigenschaften funktionieren nur bei Klassen mit neuem Stil.
    • Hinweis 2: Es ist zu versuchen, die Nebenwirkungen des Funktionsverhaltens frei zu halten, obwohl Nebenwirkungen wie das Caching im Allgemeinen in Ordnung sind.
    • Hinweis 3: Vermeidung der Verwendung von Eigenschaften für rechenintensive Operationen; die Attributnotation lässt den Aufrufer glauben, dass der Zugriff (relativ) billig ist.
  • Wenn die Klasse für die Unterklasse vorgesehen ist und Attribute hat, die nicht von Unterklassen verwendet werden sollen, sollten solche mit doppelten führenden Unterstrichen und ohne nachgestellte Unterstriche benannt werden. Dies ruft Pythons Mechanismus zur Namenszerlegung auf, bei dem der Name der Klasse in den Attributnamen zerlegt wird. Dies hilft, Kollisionen von Attributnamen zu vermeiden, falls Unterklassen versehentlich Attribute mit dem gleichen Namen enthalten.
    • Hinweis 1: Es wird nur der einfache Klassenname im manipulierten Namen verwendet, so dass man, wenn eine Unterklasse sowohl den gleichen Klassennamen als auch den gleichen Attributnamen wählt, trotzdem Namenskollisionen erhalten kann.
    • Hinweis 2: Das Verwalten von Namen kann bestimmte Verwendungen, wie Debugging und getattr(), weniger komfortabel machen. Der Algorithmus zur Namensverzerrung ist jedoch gut dokumentiert und manuell leicht durchführbar.
    • Hinweis 3: Nicht jeder mag es, Namen zu verfälschen. Versucht, die Notwendigkeit, versehentliche Namenskonflikte zu vermeiden, mit der möglichen Nutzung durch fortgeschrittene Anwender in Einklang zu bringen.