Unveränderliche Klassen in Python erzeugen

Warum brauchen wir unveränderliche Klassen?

Unbewegliche/unveränderliche Pantomine

Beliebte Beispiele für unveränderliche Klassen in Python sind Integers, Floats, Strings und Tuples. Viele funktionale Programmiersprachen, wie z. B. Haskell oder Scala, setzen auf Unveränderlichkeit als grundlegendes Konzept in ihrem Design. Der Grund dafür ist, dass unveränderliche Klassen mehrere Vorteile bei der Softwareentwicklung bieten:

  1. Thread-Sicherheit: Unveränderliche Objekte sind von Natur aus thread-sicher. Da sich ihr Zustand nach der Erstellung nicht ändert, können mehrere Threads gleichzeitig auf sie zugreifen, ohne dass Sperren oder Synchronisation erforderlich sind. Dies kann die parallele Programmierung vereinfachen und das Risiko von Wettlaufbedingungen verringern (race conditions).

  2. Vorhersehbares Verhalten: Einmal erstellte unveränderliche Objekte behalten ihren Zustand während ihrer gesamten Lebensdauer bei. Diese Vorhersehbarkeit erleichtert das Nachvollziehen des Verhaltens des Objekts, was zu robusterem und wartungsfreundlicherem Code führt.

  3. Cachefähigkeit: Unveränderliche Objekte können sicher zwischengespeichert werden, da sich ihre Werte nie ändern. Dies ist besonders vorteilhaft für die Leistung (performance), da es effiziente Memoisierungs- und Caching-Strategien ermöglicht.

  4. Vereinfacht das Testen: Da sich der Zustand eines unveränderlichen Objekts nicht ändert, wird das Testen einfacher. Man muss keine unterschiedlichen Zustände oder Mutationszenarien berücksichtigen, was das Schreiben von Tests und die Überprüfung der Korrektheit des Codes erleichtert.

  5. Konsistentes Hashing: Unveränderliche Objekte haben konsistente Hash-Codes, was für ihren Einsatz in Datenstrukturen wie Wörterbüchern oder Mengen entscheidend ist. Dies stellt sicher, dass Objekte mit denselben Werten denselben Hash-Code erzeugen, was ihren Einsatz in hashbasierten Collections-Objekten vereinfacht.

  6. Erleichtert das Debuggen: Das Debuggen kann mit unveränderlichen Objekten einfacher sein, da sich ihr Zustand nicht ändert. Sobald der Anfangszustand eines Objekts identifiziert ist, bleibt er konstant, was das Verfolgen und Verstehen des Programmflusses erleichtert.

  7. Optimal zur funktionalen Programmierung: Unveränderliche Objekte passen gut zu den Prinzipien der funktionalen Programmierung. In der funktionalen Programmierung werden Funktionen und Daten als separate Entitäten behandelt, und Unveränderlichkeit ist ein Schlüsselkonzept. Unveränderliche Objekte fördern einen funktionalen Programmierstil, der zu modularerem und zusammensetzbarerem Code führt.

  8. Verhindert unbeabsichtigte Änderungen: Bei veränderlichen Objekten können unbeabsichtigte Änderungen am Zustand auftreten, wenn Referenzen zu dem Objekt geteilt werden. Unveränderliche Objekte beseitigen dieses Risiko, da sich ihr Zustand nach der Erstellung nicht mehr ändern kann.

Erstellung unveränderlicher Klassen

Klassen mit Gettern und ohne Setter

Die folgende Klasse ImmutablRobot implementiert private Attribute __name und self.__brandname, die nur durch die Methoden get_name und get_brandname gelesen werden können, aber es gibt keine Möglichkeit, diese Attribute zu ändern, zumindest keine legale:

In [2]:
class ImmutableRobot: def __init__(self, name, brandname): self.__name = name self.__brandname = brandname def get_name(self): return self.__name def get_brandname(self): return self.__brandname robot = ImmutableRobot(name="RoboX", brandname="TechBot") print(robot.get_name()) print(robot.get_brandname()) 
RoboX TechBot 

Wir können das vorige Beispiel mit Properties umschreiben, aber keine Setter-Methoden bereitstellen. Logisch gesehen also das Gleiche wie vorher:

In [3]:
class ImmutableRobot: def __init__(self, name, brandname): self.__name = name self.__brandname = brandname @property def name(self): return self.__name @property def brandname(self): return self.__brandname robot = ImmutableRobot(name="RoboX", brandname="TechBot") print(robot.name) print(robot.brandname) try: robot.name = "RoboY" except AttributeError as e: print(e) try: robot.brandname = "NewTechBot" except AttributeError as e: print(e) 
RoboX TechBot property 'name' of 'ImmutableRobot' object has no setter property 'brandname' of 'ImmutableRobot' object has no setter 

Benutzung des dataclass-Dekorators

In [4]:
from dataclasses import dataclass @dataclass(frozen=True) class ImmutableRobot: name: str brandname: str # Example usage: robot = ImmutableRobot(name="RoboX", brandname="TechBot") print(robot.name) print(robot.brandname) try: robot.name = "RoboY" except AttributeError as e: print(e) try: robot.brandname = "NewTechBot" except AttributeError as e: print(e) 
RoboX TechBot cannot assign to field 'name' cannot assign to field 'brandname' 

Verwendung von namedtuple

Hier ist eine Alternative mit namedtuple aus dem collections-Modul:

In [6]:
from collections import namedtuple ImmutableRobot = namedtuple('ImmutableRobot', ['name', 'brandname']) # Example usage: robot = ImmutableRobot(name="RoboX", brandname="TechBot") print(robot.name) print(robot.brandname) # Attempting to modify attributes will raise an AttributeError try: robot.name = "RoboY" except AttributeError as e: print(e) try: robot.brandname = "NewTechBot" except AttributeError as e: print(e) 
RoboX TechBot can't set attribute can't set attribute 

In diesem Beispiel erzeugt namedtuple eine einfache Klasse mit benannten Feldern, und Instanzen dieser Klasse sind unveränderlich. Genau wie bei dataclass führt der Versuch, Attribute zu ändern, zu einem AttributeError.

Sowohl namedtuple als auch dataclass bieten einen prägnanten Weg, unveränderliche Klassen in Python zu erstellen. Die Wahl zwischen beiden hängt von den spezifischen Bedürfnissen und Vorlieben ab. namedtuple ist leichtgewichtiger, während dataclass zusätzliche Funktionen und Anpassungsmöglichkeiten bietet.

__slots__

'Slots' haben nichts mit der Erstellung einer unveränderlichen Klasse zu tun. Dennoch kann es missverstanden werden. Mit Hilfe von __slots__ legen wir die Anzahl der Attribute auf eine feste Menge fest. Mit anderen Worten: Das Attribut slots in Python wird verwendet, um Datenmember (Attribute) in einer Klasse explizit zu deklarieren. Es beschränkt die Erstellung neuer Attribute in Instanzen der Klasse und erlaubt nur die in slots angegebenen Attribute zu definieren. Die Attribute selbst können sich natürlich ändern, sodass die Klasse veränderlich sein kann, aber sie kann nicht dynamisch um zusätzliche Attribute erweitert werden. Der Hauptvorteil von __slots__ besteht jedoch darin, dass wir den Speicherplatz erheblich reduzieren können, der mit jeder Instanz der Klasse verbunden ist. Traditionelle Klassen speichern Attribute in einem dynamischen Wörterbuch, was zusätzlichen Speicherplatz verbraucht. Mit slots werden Attributnamen in einem Tupel gespeichert, und die Instanz reserviert direkt Speicherplatz für diese Attribute.

In [1]:
class ImmutableRobot: __slots__ = ('__name', '__brandname') def __init__(self, name, brandname): self.__name = name self.__brandname = brandname @property def name(self): return self.__name @property def brandname(self): return self.__brandname robot = ImmutableRobot(name="RoboX", brandname="TechBot") print(robot.name) print(robot.brandname) 
RoboX TechBot 

Durch die Verwendung von __slots__ kann man explizit die Attribute definieren, die Instanzen der Klasse haben werden, was dazu beitragen kann, die Speichernutzung zu reduzieren und die Leistung zu verbessern, insbesondere bei der Erstellung einer großen Anzahl von Instanzen.

In [ ]:
 
box

OOP

Die Bücher zur Webseite

Bücher zur Webseite

Im Hanser-Verlag sind vier Bücher von Bernd Klein und Philip Klein erschienen, die auf den Inhalten dieser Webseite aufbauen, aber auch über die Inhalte hinausgehen. Es lohnt sich also die Bücher zu kaufen, womit Sie außerdem diese Webseite unterstützen!

Einführung in Python3

Einführung in Python von Bernd Klein
Zum Online-Shop des Hanser-Verlages, wo Sie das Buch versandkostenfrei bestellen können!


Numerisches Python: Arbeiten mit NumPy, Matplotlib und Pandas

Bernd Klein: Python-Buch Numerisches Python Buch kaufen

Bernd Klein, Philip Klein:
Funktionale Programmierung mit Python

Bernd Klein, Philip Klein: Funktionale Programmierung mit Python Buch kaufen Python-Grundlagen | eLearning
Mit dem Hanser eCampus „Python-Grundlagen“ erhalten Einsteiger:innen eine Einführung in die Programmiersprache Python.

Python Grundlagen: elearning, Bernd Klein Buch kaufen



Bücher kaufen

Wenn Ihnen diese Webseite gefällt, - was wir natürlich sehr hoffen, - dann können Sie meine Arbeit unterstützen, wenn Sie eines meiner Bücher oder beide Bücher kaufen oder weiterempfehlen.

Die Bücher können Sie über jede Buchhandlung in Ihrer Nähe beziehen. Alternativ können Sie sie auch direkt über den Hanser-Verlag beziehen:
Bücher von Bernd Klein und Philip Klein

Spenden

Ihre Unterstützung ist dringend benötigt. Diese Webseite ist frei von Werbeblöcken und -bannern! So soll es auch bleiben! Dazu benötigen wir Ihre Unterstützung:

Weshalb wir Ihre Spende dringend benötigen erfahren Sie hier

Tutorial

Diese Webseite bietet ein Tutorial für Python. Der Unterschied zu anderen Online-Tutorials und Python-Kursen besteht darin, dass wir hier mehr Beispiele und Übungen bieten wollen. Außerdem werden komplexe Probleme in zahlreichen Diagrammen und Bildern veranschaulicht, um einen leichteren Zugang zu gewährleisten. In zahlreichen Python-Kursen hat Bernd Klein die Erfahrungen gesammelt, die in die Entwicklung dieser Webseite eingeflossen sind.

Fortgeschrittene Themen

Auf dieser Webseite befinden sich auch zahlreiche fortgeschrittene Themen zu Python, wie man sie in dieser Art vergeblich in anderen Python-Tutorials sucht. Themen, die insbesondere auch für Studierende der Informatik von besonderem Interesse sind: Turingmaschine, Endliche Automaten, Threads, Graphentheorie

Aber auch für Mathematikerinnen und Mathematiker, Ingenieurinnen und Ingenieure und andere naturwissenschaftlich Orientierte sind zum Beispiel die Einführungen in NumPy, Matplotlib und Pandas von großem Nutzen.


 


Suchen in dieser Webseite:

Webseite durchsuchen:

English Version / Englische Übersetzung

This chapter is also available in our English Python tutorial: Immutable classes in Python

Schulungen

Wenn Sie Python schnell und effizient lernen wollen, empfehlen wir den Kurs Bodenseo, Linux, Python und viele andere Kurse
Einführung in Python
von Bodenseo. Dieser Kurs wendet sich an totale Anfänger, was Programmierung betrifft. Wenn Sie bereits Erfahrung mit Python oder anderen Programmiersprachen haben, könnte der Python-Kurs für Fortgeschrittene der geeignete Kurs sein.

Python Courses


For those who prefer Python training courses in English: All our Python classes are available in English as well: Python Courses



Dem Autor Bernd Klein auf Facebook folgen:


Bernd Klein on Facebook

Spenden

Ihre Unterstützung ist dringend benötigt. Diese Webseite ist frei von Werbeblöcken und -bannern! So soll es auch bleiben! Dazu benötigen wir Ihre Unterstützung:

Weshalb wir Ihre Spende benötigen erfahren Sie hier

Spruch des Tages:

Wenn man sich fragt, ob Computer denken können, dann ist das, als ob man sich fragte, ob U-Boote schwimmen können. (frei nach Dijkstra)


Und noch ein Spruch:

Mathematiker, das sind diejenigen, die von allen Menschen noch am ehesten den Eindruck erwecken können, sie hätten die unüberbrückbare Kluft zwischen Mensch und Logik überwunden.

Hilfe

Diese Dokumentation zu Python mit Einführung und Tutorial wurde mit großer Sorgfalt erstellt und wird ständig erweitert. Dennoch können wir für die Korrektheit der Texte und der zahlreichen Beispiele keine Garantie übernehmen. Die Benutzung und Anwendung der Beispiele erfolgt auf eigenes Risiko. Wir freuen uns über alle Anregungen und Fehlerkorrekturen!



Datenschutzerklärung

Datenschutzerklärung nach DSGVO