collections. namedtuple
Tworzy krotki z nazwanymi polami: dane odczytasz przez student.points zamiast student[2], a obiekt pozostaje niezmienny.
- Zwraca
- Nową klasę, która dziedziczy po
tuple.
Przykład
#from collections import namedtuple
Student = namedtuple("Student", ["name", "world", "points"])
ania = Student("Ania", 7, 250)
print(ania)
print(ania.name, ania.points)
print(ania[1], len(ania))
name, world, points = ania
print(f"{name} jest w świecie {world}")Definicja i zastosowanie
#Funkcja namedtuple() z modułu collections tworzy nową klasę krotek, w których każde pole ma nazwę. Zamiast pamiętać, że w krotce ("Ania", 7, 250) punkty są pod indeksem 2, piszesz student.points. Obiekty nadal są zwykłymi krotkami, więc działa indeksowanie, rozpakowywanie, porównywanie i len().
Jak każda krotka, obiekt jest niezmienny: przypisanie do pola zgłasza AttributeError. Nową wersję ze zmienionym polem tworzy metoda _replace(), a _asdict() zamienia obiekt na słownik. Atrybut _fields zawiera nazwy pól, a _make() tworzy obiekt z dowolnej sekwencji, np. wiersza z pliku CSV. Podkreślnik w tych nazwach nie oznacza, że są prywatne, tylko zapobiega konfliktom z nazwami Twoich pól.
Nowocześniejszy zapis to klasa dziedzicząca po typing.NamedTuple, w której pola deklaruje się z adnotacjami typów, podobnie jak w @dataclass. Gdy potrzebujesz obiektu, którego pola można zmieniać, wybierz właśnie @dataclass.
Składnia
#from collections import namedtuple
Nazwa = namedtuple("Nazwa", ["pole1", "pole2"], defaults=None)
obiekt = Nazwa(wartosc1, wartosc2)
obiekt.pole1
obiekt._replace(pole1=nowa_wartosc)
obiekt._asdict()Parametry
#typename
str
Nazwa nowej klasy, widoczna m.in. wrepr(). Zwykle taka sama jak nazwa zmiennej.field_names
lista napisów lub napis
Nazwy pól, np.["x", "y"]albo"x y".defaults
sekwencja, opcjonalna
Wartości domyślne dla ostatnich pól.
Więcej przykładów
#from collections import namedtuple
Student = namedtuple("Student", "name points level", defaults=[1])
kuba = Student("Kuba", 80)
print(kuba)
try:
kuba.points = 120
except AttributeError:
print("Pola nie można zmienić")
promoted = kuba._replace(points=120, level=2)
print(promoted)
print(promoted._asdict())
print(Student._fields)from typing import NamedTuple
class Point(NamedTuple):
x: float
y: float = 0.0
def distance(self):
return (self.x ** 2 + self.y ** 2) ** 0.5
p = Point(3, 4)
print(p, p.distance())
print(Point(1.5))
print(sorted([Point(2, 1), Point(1, 5), Point(1, 2)]))Adnotacje nie zamieniają typów: Point(3, 4) przechowuje liczby całkowite. Sortowanie porównuje pola po kolei, jak w zwykłych krotkach.
import csv
from collections import namedtuple
lines = ["name,world,points", "Ania,7,250", "Kuba,2,80"]
reader = csv.reader(lines)
Row = namedtuple("Row", next(reader))
for row in map(Row._make, reader):
print(row.name, int(row.points))Dobre praktyki
#- Metody
_replace(),_asdict()i_make()są publiczne mimo podkreślnika. Podkreślnik chroni przed konfliktem z nazwami Twoich pól. - Namedtuple dobrze sprawdza się przy zwracaniu kilku wartości z funkcji: wynik rozpakujesz jak krotkę albo odczytasz po nazwach pól.
- Jeśli pola mają się zmieniać albo klasa potrzebuje wielu metod, użyj
@dataclass.
Powiązane hasła
#- tuple()Tworzy krotkę: niezmienną sekwencję elementów.
- Rozpakowywanie sekwencjiPrzypisanie elementów krotki lub listy do kilku zmiennych naraz.
- @dataclassDekorator, który na podstawie pól z adnotacjami typów generuje __init__, __repr__ i __eq__ klasy przechowującej dane.
- typingAdnotacje typów: opis, jakich wartości oczekuje funkcja i co zwraca. Sprawdzają je edytory i narzędzia takie jak mypy.
- csvOdczyt i zapis plików CSV, czyli tabel zapisanych jako tekst, w których wartości oddziela przecinek lub średnik.
Widzisz błąd albo brakuje przykładu? Napisz do nas.