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.
Na tej stronie

Przykład

#
Python
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}")
Wynikzapisany wynik, możesz go sprawdzić
Student(name='Ania', world=7, points=250)
Ania 250
7 3
Ania jest w świecie 7

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

#
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. w repr(). 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

#
Niezmienność, _replace() i _asdict()
Python
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)
Wynikzapisany wynik, możesz go sprawdzić
Student(name='Kuba', points=80, level=1)
Pola nie można zmienić
Student(name='Kuba', points=120, level=2)
{'name': 'Kuba', 'points': 120, 'level': 2}
('name', 'points', 'level')
typing.NamedTuple z adnotacjami typów
Python
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)]))
Wynikzapisany wynik, możesz go sprawdzić
Point(x=3, y=4) 5.0
Point(x=1.5, y=0.0)
[Point(x=1, y=2), Point(x=1, y=5), Point(x=2, y=1)]

Adnotacje nie zamieniają typów: Point(3, 4) przechowuje liczby całkowite. Sortowanie porównuje pola po kolei, jak w zwykłych krotkach.

_make() i wiersze z pliku CSV
Python
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))
Wynikzapisany wynik, możesz go sprawdzić
Ania 250
Kuba 80

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

#

Widzisz błąd albo brakuje przykładu? Napisz do nas.