In diesem Artikel geht es um den Data Class Builder typing.NamedTuple. Es handelt sich dabei um die modernere, typisierte Variante zu collections.namedtuple, über die ihr in diesem Artikel mehr Informationen findet.
Wenn ihr collections.namedtuple kennt, dann werdet ich euch schnell mit typing.NamedTuple anfreunden. Es wird hier ebenfalls eine Klasse von tuple erzeugt. Dazu nutzt Python eine Metaklasse, die von tuple erbt. Um dies zu Demonstrieren greife ich das Beispiel aus dem Artikel zu collections.namedtuple auf und zeige die typing.NamedTuple-Version:
from typing import NamedTuple
class Hessen(NamedTuple):
capital: str
population: int
# Check if Hessen is a subclass of tuple
print(issubclass(Hessen, tuple)) # TrueBei typing.NamedTuple könnt ihr explizit angeben, welcher Datentyp erwartet wird. Des Weiteren kann man anhand der Ausgabe von print(issubclass(Hessen, tuple)) erkennen kann, dass es sich um eine Subklasse von tuple handelt.
Außerdem ist es möglich, den Attributen Standardwerte zuzuweisen:
from typing import NamedTuple
class Hessen(NamedTuple):
capital: str = "Wiesbaden"
population: intEin zugriff auf die Attribute erfolgt entweder über den Index oder den Namen:
from typing import NamedTuple
class Hessen(NamedTuple):
capital: str = "Wiesbaden"
population: int
hessen = Hessen(population=6_295_017)
# Zugriff über den Namen
print(hessen.population) # 6295017
print(hessen.capital) # Wiesbaden
# Zugriff über den Index
print(hessen[0]) # 6295017
# Ausgabe des NamedTuples
print(hessen) # Hessen(population=6295017, capital='Wiesbaden')Ein typing.NamedTuple ist unveränderlich. Nach der Erzeugung der Klasse könne die Werte nicht mehr geändert werden. Folgender Code führt zu einem AttributeError:
from typing import NamedTuple
class Hessen(NamedTuple):
capital: str = "Wiesbaden"
population: int
hessen = Hessen(population=7_400_000) # -> AttributeErrorFazit
Wenn ihr möchtet, dass die Datentypen angegeben werden könne, solltet ihr typing.NamedTuple anstelle von collections.namedtuple verwenden. Beide Typen sind aber eher für kleine Datenstrukturen geeignet, bei denen sich die Werte nicht ändern sollen. Für größere Datenstrukturen bietet es sich an, eine reguläre Klasse mit dem @dataclass-Decorator zu verwenden. Bei solchen Datenklassen sind die Werte zudem veränderbar.