Kurz: Zwei Werkzeuge machen Klassen im Alltag kürzer und sicherer: Dataclasses nehmen dir Routinecode ab, Properties kontrollieren den Zugriff auf Attribute.
Teil des Kurses Python
Zwei Werkzeuge machen Klassen im Alltag kürzer und sicherer: Dataclasses nehmen dir Routinecode ab, Properties kontrollieren den Zugriff auf Attribute.
Dataclasses
Für Klassen, die vor allem Daten halten, schreibt man mit @dataclass nur noch die Felder. Python erzeugt __init__, __repr__ und __eq__ selbst:
from dataclasses import dataclass
@dataclass
class Person:
name: str
alter: int
stadt: str = "Köln"
p = Person("Mia", 17)
print(p)
print(p == Person("Mia", 17))
p.alter += 1
print(p.alter)Ausgabe:
Person(name='Mia', alter=17, stadt='Köln')
True
18Nützliche Optionen
from dataclasses import dataclass, field, asdict, replace
@dataclass(frozen=True, order=True)
class Artikel:
preis: float
name: str = field(compare=False)
tags: tuple = ()
a = Artikel(2.5, "Stift")
b = Artikel(1.0, "Heft")
print(sorted([a, b]))
print(asdict(a))
print(replace(a, preis=9.0))
try:
a.preis = 3
except Exception as e:
print(type(e).__name__)Ausgabe:
[Artikel(preis=1.0, name='Heft', tags=()), Artikel(preis=2.5, name='Stift', tags=())]
{'preis': 2.5, 'name': 'Stift', 'tags': ()}
Artikel(preis=9.0, name='Stift', tags=())
FrozenInstanceError| Option | Wirkung |
|---|---|
frozen=True | unveränderlich, auch hashbar |
order=True | erzeugt Vergleiche (<, >) über die Felder |
field(default_factory=list) | veränderlicher Standardwert pro Objekt |
field(compare=False) | Feld beim Vergleichen ignorieren |
Achtung
Als Standardwert nie
[]oder{}direkt verwenden, sondernfield(default_factory=list). Sonst teilen sich alle Objekte dieselbe Liste.
Properties
Eine Property sieht von außen wie ein Attribut aus, ruft aber Code auf. So prüfst du Werte oder berechnest sie bei Bedarf:
class Temperatur:
def __init__(self, celsius):
self.celsius = celsius # läuft durch den Setter
@property
def celsius(self):
return self._celsius
@celsius.setter
def celsius(self, wert):
if wert < -273.15:
raise ValueError("Unter dem absoluten Nullpunkt")
self._celsius = wert
@property
def fahrenheit(self): # nur lesbar, wird berechnet
return self._celsius * 9 / 5 + 32
t = Temperatur(25)
print(t.celsius, t.fahrenheit)
t.celsius = 100
print(t.fahrenheit)
try:
t.celsius = -300
except ValueError as e:
print("Fehler:", e)Ausgabe:
25 77.0
212.0
Fehler: Unter dem absoluten Nullpunktslots
Mit __slots__ legst du fest, welche Attribute ein Objekt haben darf. Das spart Speicher und verhindert Tippfehler bei Attributnamen:
class Punkt:
__slots__ = ("x", "y")
def __init__(self, x, y):
self.x, self.y = x, y
p = Punkt(1, 2)
try:
p.z = 3
except AttributeError:
print("kein Attribut z erlaubt")Ausgabe:
kein Attribut z erlaubtMerke
@dataclasserzeugt__init__,__repr__,__eq__automatischfrozen=Truemacht unveränderlich,order=Truesortierbar- Veränderliche Standardwerte mit
field(default_factory=...) @propertymacht aus einer Methode ein Attribut,@x.setterprüft Zuweisungen__slots__beschränkt Attribute und spart Speicher
Übungsaufgabe
Schreibe eine Dataclass Buch mit Titel, Autor und Seitenzahl. Ergänze eine Property dick, die True liefert, wenn das Buch mehr als 500 Seiten hat.
Quiz zur Selbstkontrolle
Was erzeugt @dataclass automatisch?
- init, repr und eq (richtig)
- Nur str
- Eine Datenbanktabelle
- Nichts, es ist nur ein Kommentar
Wozu dient eine Property mit Setter?
- Zuweisungen an ein Attribut zu prüfen (richtig)
- Attribute zu löschen
- Klassen zu vererben
- Schleifen zu beschleunigen
Welchen Standardwert nimmst du für eine leere Liste in einer Dataclass?
- field(default_factory=list) (richtig)
- []
- list
- None ohne Prüfung
Weiter im Kurs
Zurück: Spezielle Methoden (Dunder)
Weiter: Typ-Hints
Alle Kapitel: Python im Überblick