Co to są „nazwane krotki” w Pythonie?


906

Czytając zmiany w Pythonie 3.1 , znalazłem coś ... nieoczekiwanego:

Krotka sys.version_info jest teraz krotką nazwaną :

Nigdy wcześniej nie słyszałem o nazwanych krotkach i myślałem, że elementy mogą być indeksowane według liczb (jak w krotkach i listach) lub według kluczy (jak w nagraniach). Nigdy nie spodziewałem się, że można je indeksować w obie strony.

Tak więc moje pytania to:

  • Jakie są nazwane krotki?
  • Jak z nich korzystać?
  • Dlaczego / kiedy powinienem używać krotek nazwanych zamiast krotek normalnych?
  • Dlaczego / kiedy powinienem używać normalnych krotek zamiast krotek nazwanych?
  • Czy istnieje jakaś „lista nazwanych” (zmienna wersja nazwanej krotki)?

Odpowiedzi:


1196

Krotki nazwane są w zasadzie łatwymi do utworzenia, lekkimi typami obiektów. Do nazwanych instancji krotek można odwoływać się za pomocą obiektowego dereferencji zmiennych lub standardowej składni krotek. Można ich używać podobnie structlub innych popularnych typów rekordów, z tym wyjątkiem, że są one niezmienne. Zostały dodane w Python 2.6 i Python 3.0, chociaż istnieje przepis na implementację w Python 2.4 .

Na przykład często reprezentuje się punkt jako krotkę (x, y). Prowadzi to do następującego kodu:

pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)

Używanie nazwanej krotki staje się bardziej czytelne:

from collections import namedtuple
Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)

Jednak nazwane krotki są nadal kompatybilne wstecz z normalnymi krotkami, więc następujące działania nadal będą działać:

Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)

from math import sqrt
# use index referencing
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
 # use tuple unpacking
x1, y1 = pt1

Dlatego powinieneś używać krotek nazwanych zamiast krotek wszędzie tam, gdzie według ciebie notacja obiektowa sprawi, że Twój kod będzie bardziej pythonowy i łatwiejszy do odczytania . Osobiście zacząłem je wykorzystywać do reprezentowania bardzo prostych typów wartości, szczególnie gdy przekazuję je jako parametry funkcji. Sprawia, że ​​funkcje są bardziej czytelne, bez dostrzegania kontekstu pakowania krotek.

Ponadto można również zastąpić zwykłe niezmienne klasy, które nie mają żadnych funkcji , a jedynie pola z nimi. Możesz nawet użyć nazwanych typów krotek jako klas podstawowych:

class Point(namedtuple('Point', 'x y')):
    [...]

Jednak, podobnie jak w przypadku krotek, atrybuty w krotkach nazwanych są niezmienne:

>>> Point = namedtuple('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
AttributeError: can't set attribute

Jeśli chcesz mieć możliwość zmiany wartości, potrzebujesz innego typu. Istnieje przydatny przepis na modyfikowalne typy rekordów, które pozwalają ustawić nowe wartości atrybutów.

>>> from rcdtype import *
>>> Point = recordtype('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
>>> print(pt1[0])
    2.0

Nie znam jednak żadnej formy „nazwanej listy”, która pozwala dodawać nowe pola. W takiej sytuacji możesz po prostu użyć słownika. Krotki nazwane można konwertować na słowniki, za pomocą pt1._asdict()których zwraca się, {'x': 1.0, 'y': 5.0}i można nimi operować za pomocą wszystkich zwykłych funkcji słownika.

Jak już wspomniano, należy sprawdzić dokumentację, aby uzyskać więcej informacji, na podstawie których skonstruowano te przykłady.


35
z Pythona 3.7, rozważ również klasy danych jako alternatywę (backport dostępny do wersji 3.6, ale nie wcześniejszych wersji)
innov8 30.04.2018

3
Jeśli potrzebujesz zmiennego typu rekordu - użyj prostej klasy ze zdefiniowanym__slots__
madzohan

jaki jest główny powód używania klas rcdtype zamiast dataclass
Voyager

Alternatywą dla dict jest słownik atrybutów stackoverflow.com/questions/4984647/…
mrgloom,

Ponieważ jest to odpowiedź, na którą zawsze się znajdujesz, warto wspomnieć, że teraz istnieje również typing.NamedTupleopcja, która pozwala na podpowiedzi do typów i jest szczególnie wygodna w przypadku podklas.
DerWeh,

101

namedtuple to fabryczna funkcja do tworzenia klasy krotek. Dzięki tej klasie możemy tworzyć krotki, które można wywoływać również z nazwy.

import collections

#Create a namedtuple class with names "a" "b" "c"
Row = collections.namedtuple("Row", ["a", "b", "c"], verbose=False, rename=False)   

row = Row(a=1,b=2,c=3) #Make a namedtuple from the Row class we created

print row    #Prints: Row(a=1, b=2, c=3)
print row.a  #Prints: 1
print row[0] #Prints: 1

row = Row._make([2, 3, 4]) #Make a namedtuple from a list of values

print row   #Prints: Row(a=2, b=3, c=4)

5
parametry szczegółowe i zmiana nazwy są domyślnie ustawione na False, więc nie trzeba jawnie ustawiać tej wartości.
Trismegistos,

namedtuple is a factory function for making a tuple class.to chyba jedyna poprawna odpowiedź tutaj: P
Mr_Mrs_D

90

Jakie są nazwane krotki?

Krotka o nazwie to krotka.

Robi wszystko, co może krotka.

Ale to coś więcej niż krotka.

Jest to specyficzna podklasa krotki, która jest programowo tworzona zgodnie ze specyfikacją, z nazwanymi polami i stałą długością.

To, na przykład, tworzy podklasę krotki, a poza tym, że ma stałą długość (w tym przypadku trzy), można jej używać wszędzie tam, gdzie krotka jest używana bez zerwania. Jest to znane jako substytucyjność Liskowa.

Nowość w Pythonie 3.6 , możemy użyć definicji klasytyping.NamedTupledo utworzenia parametru o nazwie:

from typing import NamedTuple

class ANamedTuple(NamedTuple):
    """a docstring"""
    foo: int
    bar: str
    baz: list

Powyższe jest takie samo, jak poniżej, z tym że powyższe dodatkowo zawiera adnotacje typu i dokumentację. Poniższe jest dostępne w Python 2+:

>>> from collections import namedtuple
>>> class_name = 'ANamedTuple'
>>> fields = 'foo bar baz'
>>> ANamedTuple = namedtuple(class_name, fields)

To tworzy instancję:

>>> ant = ANamedTuple(1, 'bar', [])

Możemy to sprawdzić i wykorzystać jego atrybuty:

>>> ant
ANamedTuple(foo=1, bar='bar', baz=[])
>>> ant.foo
1
>>> ant.bar
'bar'
>>> ant.baz.append('anything')
>>> ant.baz
['anything']

Głębsze wyjaśnienie

Aby zrozumieć nazwane krotki, najpierw musisz wiedzieć, czym jest krotka. Krotka jest zasadniczo niezmienną (nie można jej zmienić w pamięci) listą.

Oto jak możesz użyć zwykłej krotki:

>>> student_tuple = 'Lisa', 'Simpson', 'A'
>>> student_tuple
('Lisa', 'Simpson', 'A')
>>> student_tuple[0]
'Lisa'
>>> student_tuple[1]
'Simpson'
>>> student_tuple[2]
'A'

Możesz rozwinąć krotkę za pomocą iterowalnego rozpakowywania:

>>> first, last, grade = student_tuple
>>> first
'Lisa'
>>> last
'Simpson'
>>> grade
'A'

Krotki nazwane to krotki, które umożliwiają dostęp do ich elementów według nazwy zamiast po prostu indeksu!

Tworzysz nazwę o nazwie:

>>> from collections import namedtuple
>>> Student = namedtuple('Student', ['first', 'last', 'grade'])

Możesz także użyć pojedynczego ciągu z nazwami oddzielonymi spacjami, nieco bardziej czytelne użycie interfejsu API:

>>> Student = namedtuple('Student', 'first last grade')

Jak z nich korzystać?

Możesz zrobić wszystko, co mogą zrobić krotki (patrz wyżej), a także wykonać następujące czynności:

>>> named_student_tuple = Student('Lisa', 'Simpson', 'A')
>>> named_student_tuple.first
'Lisa'
>>> named_student_tuple.last
'Simpson'
>>> named_student_tuple.grade
'A'
>>> named_student_tuple._asdict()
OrderedDict([('first', 'Lisa'), ('last', 'Simpson'), ('grade', 'A')])
>>> vars(named_student_tuple)
OrderedDict([('first', 'Lisa'), ('last', 'Simpson'), ('grade', 'A')])
>>> new_named_student_tuple = named_student_tuple._replace(first='Bart', grade='C')
>>> new_named_student_tuple
Student(first='Bart', last='Simpson', grade='C')

Komentator zapytał:

Gdzie w dużym skrypcie lub programie definiuje się nazwaną krotkę?

Typy, które tworzysz, namedtuplesą w zasadzie klasami, które możesz tworzyć za pomocą prostego skrótu. Traktuj je jak zajęcia. Zdefiniuj je na poziomie modułu, aby marynarka i inni użytkownicy mogli je znaleźć.

Przykład roboczy na poziomie globalnego modułu:

>>> from collections import namedtuple
>>> NT = namedtuple('NT', 'foo bar')
>>> nt = NT('foo', 'bar')
>>> import pickle
>>> pickle.loads(pickle.dumps(nt))
NT(foo='foo', bar='bar')

A to pokazuje brak wyszukiwania definicji:

>>> def foo():
...     LocalNT = namedtuple('LocalNT', 'foo bar')
...     return LocalNT('foo', 'bar')
... 
>>> pickle.loads(pickle.dumps(foo()))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class '__main__.LocalNT'>: attribute lookup LocalNT on __main__ failed

Dlaczego / kiedy powinienem używać krotek nazwanych zamiast krotek normalnych?

Używaj ich, gdy poprawia kod, aby semantyka elementów krotkowych była wyrażona w kodzie.

Możesz użyć ich zamiast obiektu, jeśli w innym przypadku używałbyś obiektu z niezmiennymi atrybutami danych i bez funkcji.

Możesz także podzielić je na klasy, aby dodać funkcjonalność, na przykład :

class Point(namedtuple('Point', 'x y')):
    """adding functionality to a named tuple"""
        __slots__ = ()
        @property
        def hypot(self):
            return (self.x ** 2 + self.y ** 2) ** 0.5
        def __str__(self):
            return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)

Dlaczego / kiedy powinienem używać normalnych krotek zamiast krotek nazwanych?

Prawdopodobnie regresją byłoby przejście od używania krotek nazwanych do krotek. Początkowa decyzja projektowa skupia się na tym, czy koszt dodatkowego kodu jest wart poprawionej czytelności, gdy używana jest krotka.

Nie ma dodatkowej pamięci używanej przez krotki nazwane w porównaniu krotek.

Czy istnieje jakaś „lista nazwanych” (zmienna wersja nazwanej krotki)?

Szukasz obiektu z wycięciem, który implementuje wszystkie funkcje listy o statycznym rozmiarze lub listy o podklasach, która działa jak nazwana krotka (i która w jakiś sposób blokuje zmianę wielkości listy).

Rozbudowany, a może nawet zastępujący Liskov, przykład pierwszego:

from collections import Sequence

class MutableTuple(Sequence): 
    """Abstract Base Class for objects that work like mutable
    namedtuples. Subclass and define your named fields with 
    __slots__ and away you go.
    """
    __slots__ = ()
    def __init__(self, *args):
        for slot, arg in zip(self.__slots__, args):
            setattr(self, slot, arg)
    def __repr__(self):
        return type(self).__name__ + repr(tuple(self))
    # more direct __iter__ than Sequence's
    def __iter__(self): 
        for name in self.__slots__:
            yield getattr(self, name)
    # Sequence requires __getitem__ & __len__:
    def __getitem__(self, index):
        return getattr(self, self.__slots__[index])
    def __len__(self):
        return len(self.__slots__)

Aby użyć, wystarczy podklasę i zdefiniować __slots__:

class Student(MutableTuple):
    __slots__ = 'first', 'last', 'grade' # customize 


>>> student = Student('Lisa', 'Simpson', 'A')
>>> student
Student('Lisa', 'Simpson', 'A')
>>> first, last, grade = student
>>> first
'Lisa'
>>> last
'Simpson'
>>> grade
'A'
>>> student[0]
'Lisa'
>>> student[2]
'A'
>>> len(student)
3
>>> 'Lisa' in student
True
>>> 'Bart' in student
False
>>> student.first = 'Bart'
>>> for i in student: print(i)
... 
Bart
Simpson
A

44

imienniki są świetną funkcją, są idealnym pojemnikiem na dane. Gdy trzeba „przechowywać” dane, należy użyć krotek lub słowników, takich jak:

user = dict(name="John", age=20)

lub:

user = ("John", 20)

Słownikowe podejście jest przytłaczające, ponieważ dyktowanie jest zmienne i wolniejsze niż krotki. Z drugiej strony krotki są niezmienne i lekkie, ale brak ich czytelności dla dużej liczby wpisów w polach danych.

imiona są idealnym kompromisem dla dwóch podejść, mają doskonałą czytelność, lekkość i niezmienność (a ponadto są polimorficzne!).


9
Należy pamiętać, że imienniki są znacznie wolniejsze niż dyktony, jeśli uzyskuje się dostęp do ich atrybutów według nazwy: w ntuple.fooporównaniu z ntuple[1]tym drugim jest znacznie szybszy. Więcej na ten temat: stackoverflow.com/questions/2646157/...
Rotareti

28

Krotki nazwane umożliwiają zgodność wsteczną z kodem, który sprawdza taką wersję

>>> sys.version_info[0:2]
(3, 1)

jednocześnie pozwalając, aby kod w przyszłości był bardziej jednoznaczny dzięki tej składni

>>> sys.version_info.major
3
>>> sys.version_info.minor
1

12

namedtuple

jest jednym z najprostszych sposobów na oczyszczenie kodu i uczynienie go bardziej czytelnym. Dokumentuje sam, co dzieje się w krotce. Instancje nazwane są tak samo wydajne pod względem pamięci jak zwykłe krotki, ponieważ nie mają słowników dla poszczególnych wystąpień, co czyni je szybszymi niż słowniki.

from collections import namedtuple

Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])

 p = Color(170, 0.1, 0.6)
 if p.saturation >= 0.5:
     print "Whew, that is bright!"
 if p.luminosity >= 0.5:
     print "Wow, that is light"

Bez nazywania każdego elementu w krotce, brzmiałby on następująco:

p = (170, 0.1, 0.6)
if p[1] >= 0.5:
    print "Whew, that is bright!"
if p[2]>= 0.5:
   print "Wow, that is light"

O wiele trudniej jest zrozumieć, co się dzieje w pierwszym przykładzie. W nazwie nazwa, każde pole ma nazwę. I masz do niego dostęp według nazwy zamiast pozycji lub indeksu. Zamiast tego p[1]możemy nazwać to p.saturation. Łatwiej to zrozumieć. I wygląda na czystsze.

Utworzenie instancji parametru namedtu jest łatwiejsze niż utworzenie słownika.

# dictionary
>>>p = dict(hue = 170, saturation = 0.1, luminosity = 0.6)
>>>p['hue']
170

#nametuple
>>>from collections import namedtuple
>>>Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])
>>>p = Color(170, 0.1, 0.6)
>>>p.hue
170

Kiedy możesz użyć namedtuple

  1. Jak już wspomniano, nazwa-imtu znacznie ułatwia zrozumienie krotek. Jeśli więc chcesz odwoływać się do elementów w krotce, wówczas tworzenie ich jako nazwanych imion ma sens.
  2. Oprócz tego, że jest lżejszy niż słownik, namedtuple zachowuje kolejność w przeciwieństwie do słownika.
  3. Tak jak w powyższym przykładzie, łatwiej jest utworzyć instancję nazwaną niż słownik. Odwoływanie się do elementu w nazwanej krotce wygląda na czystsze niż słownik. p.hueraczej niż p['hue'].

Składnia

collections.namedtuple(typename, field_names[, verbose=False][, rename=False])
  • namedtuple znajduje się w bibliotece kolekcji.
  • typename: To jest nazwa nowej podklasy krotek.
  • nazwy_pola: Sekwencja nazw dla każdego pola. Może to być sekwencja jak na liście ['x', 'y', 'z']lub w łańcuchu x y z(bez przecinków, tylko białe znaki) lub x, y, z.
  • rename: Jeśli Truezmieniono nazwę , nieprawidłowe nazwy pól są automatycznie zastępowane nazwami pozycyjnymi. Na przykład ['abc', 'def', 'ghi','abc']jest konwertowany na ['abc', '_1', 'ghi', '_3'], eliminując słowo kluczowe 'def'(ponieważ jest to słowo zastrzeżone do definiowania funkcji) i zduplikowaną nazwę pola 'abc'.
  • verbose: Jeśli jest verbose True, definicja klasy jest drukowana tuż przed budowaniem.

Nadal możesz uzyskać dostęp do imienników według ich pozycji, jeśli tak wybierzesz. p[1] == p.saturation. Nadal rozpakowuje się jak zwykła krotka.

Metody

Obsługiwane są wszystkie zwykłe metody krotek . Np .: min (), max (), len (), in, not in, concatenation (+), index, slice, itp. I jest kilka dodatkowych dla namedtuple. Uwaga: wszystkie zaczynają się od podkreślenia. _replace, _make, _asdict.

_replace Zwraca nową instancję nazwanej krotki, zastępując określone pola nowymi wartościami.

Składnia

somenamedtuple._replace(kwargs)

Przykład

>>>from collections import namedtuple

>>>Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])
>>>p = Color(170, 0.1, 0.6)

>>>p._replace(hue=87)
Color(87, 0.1, 0.6)

>>>p._replace(hue=87, saturation=0.2)
Color(87, 0.2, 0.6)

Uwaga : Nazwy pól nie są w cudzysłowach; są tutaj słowami kluczowymi. Pamiętaj : Tuple są niezmienne - nawet jeśli są nazwane świątyniami i mają odpowiednią _replacemetodę. _replaceWytwarza newz nich; nie modyfikuje oryginału ani nie zastępuje starej wartości. Możesz oczywiście zapisać nowy wynik w zmiennej.p = p._replace(hue=169)

_make

Tworzy nową instancję z istniejącej sekwencji lub iterowalną.

Składnia

somenamedtuple._make(iterable)

Przykład

 >>>data = (170, 0.1, 0.6)
 >>>Color._make(data)
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make([170, 0.1, 0.6])  #the list is an iterable
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make((170, 0.1, 0.6))  #the tuple is an iterable
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make(170, 0.1, 0.6) 
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<string>", line 15, in _make
TypeError: 'float' object is not callable

Co się stało z ostatnim? Element w nawiasie powinien być iterowalny. Tak więc lista lub krotka w nawiasach działa, ale sekwencja wartości bez uwzględnienia jako iterowalnego zwraca błąd.

_asdict

Zwraca nowy OrdersDict, który mapuje nazwy pól na odpowiadające im wartości.

Składnia

somenamedtuple._asdict()

Przykład

 >>>p._asdict()
OrderedDict([('hue', 169), ('saturation', 0.1), ('luminosity', 0.6)])

Odniesienie : https://www.reddit.com/r/Python/comments/38ee9d/intro_to_namedtuple/

Istnieje także lista nazwana, która jest podobna do nazwanej krotki, ale można ją modyfikować https://pypi.python.org/pypi/namedlist


Należy jednak pamiętać, że zgodnie z PEP8 pojedynczy znak podkreślenia jest uważany za „słaby„ wskaźnik „do użytku wewnętrznego” z własnym zachowaniem. Ostrożnie podczas korzystania z funkcji zaczynających się od _!
Jens

8

Co to jest namepleple?

Jak sama nazwa wskazuje, namedtuple to krotka o nazwie. W krotce standardowej uzyskujemy dostęp do elementów za pomocą indeksu, natomiast namedtuple pozwala użytkownikowi zdefiniować nazwę elementów. Jest to bardzo przydatne, szczególnie podczas przetwarzania plików csv (wartości oddzielonych przecinkami) i pracy ze złożonymi i dużymi zbiorami danych, w których kod staje się nieporządny przy użyciu indeksów (nie tak pythonicznych).

Jak z nich korzystać?

>>>from collections import namedtuple
>>>saleRecord = namedtuple('saleRecord','shopId saleDate salesAmout totalCustomers')
>>>
>>>
>>>#Assign values to a named tuple 
>>>shop11=saleRecord(11,'2015-01-01',2300,150) 
>>>shop12=saleRecord(shopId=22,saleDate="2015-01-01",saleAmout=1512,totalCustomers=125)

Czytanie

>>>#Reading as a namedtuple
>>>print("Shop Id =",shop12.shopId)
12
>>>print("Sale Date=",shop12.saleDate)
2015-01-01
>>>print("Sales Amount =",shop12.salesAmount)
1512
>>>print("Total Customers =",shop12.totalCustomers)
125

Ciekawy scenariusz przetwarzania CSV:

from csv import reader
from collections import namedtuple

saleRecord = namedtuple('saleRecord','shopId saleDate totalSales totalCustomers')
fileHandle = open("salesRecord.csv","r")
csvFieldsList=csv.reader(fileHandle)
for fieldsList in csvFieldsList:
    shopRec = saleRecord._make(fieldsList)
    overAllSales += shopRec.totalSales;

print("Total Sales of The Retail Chain =",overAllSales)

5

W Pythonie wewnątrz jest dobre wykorzystanie kontenera zwanego krotką nazwaną, można go użyć do stworzenia definicji klasy i ma wszystkie cechy oryginalnej krotki.

Używanie nazwanej krotki zostanie zastosowane bezpośrednio do domyślnego szablonu klasy w celu wygenerowania prostej klasy, ta metoda pozwala na dużo kodu w celu poprawy czytelności, a także jest bardzo wygodna podczas definiowania klasy.


2

Innym sposobem (nowym sposobem) użycia nazwanej krotki jest użycie NamedTuple z paczki do pisania: Wpisz wskazówki w namedtuple

Skorzystajmy z przykładu najwyższej odpowiedzi w tym poście, aby zobaczyć, jak z niej skorzystać.

(1) Przed użyciem nazwanej krotki kod wygląda następująco:

pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
print(line_length)

(2) Teraz używamy nazwanej krotki

from typing import NamedTuple, Number

odziedzicz klasę NamedTuple i zdefiniuj nazwę zmiennej w nowej klasie. test to nazwa klasy.

class test(NamedTuple):
x: Number
y: Number

utwórz instancje z klasy i przypisz im wartości

pt1 = test(1.0, 5.0)   # x is 1.0, and y is 5.0. The order matters
pt2 = test(2.5, 1.5)

użyj zmiennych z instancji do obliczenia

line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)
print(line_length)

1

Spróbuj tego:

collections.namedtuple()

Zasadniczo namedtuplessą łatwe do utworzenia, lekkie typy obiektów. Zamieniają krotki w wygodne pojemniki do prostych zadań. Dzięki namedtuplesnie musisz używać indeksów całkowitych w celu uzyskania dostępu do członków krotki.

Przykłady:

Kod 1:

>>> from collections import namedtuple

>>> Point = namedtuple('Point','x,y')

>>> pt1 = Point(1,2)

>>> pt2 = Point(3,4)

>>> dot_product = ( pt1.x * pt2.x ) +( pt1.y * pt2.y )

>>> print dot_product
11

Kod 2:

>>> from collections import namedtuple

>>> Car = namedtuple('Car','Price Mileage Colour Class')

>>> xyz = Car(Price = 100000, Mileage = 30, Colour = 'Cyan', Class = 'Y')

>>> print xyz

Car(Price=100000, Mileage=30, Colour='Cyan', Class='Y')
>>> print xyz.Class
Y

-1

Wszyscy inni już na to odpowiedzieli, ale myślę, że wciąż mam coś jeszcze do dodania.

Namedtuple można intuicyjnie uznać za skrót do zdefiniowania klasy.

Zobacz kłopotliwy i konwencjonalny sposób zdefiniowania class.

class Duck:
    def __init__(self, color, weight):
        self.color = color
        self.weight = weight
red_duck = Duck('red', '10')

    In [50]: red_duck
    Out[50]: <__main__.Duck at 0x1068e4e10>
    In [51]: red_duck.color
    Out[51]: 'red'

Jeśli chodzi o namedtuple

from collections import namedtuple
Duck = namedtuple('Duck', ['color', 'weight'])
red_duck = Duck('red', '10')

In [54]: red_duck
Out[54]: Duck(color='red', weight='10')
In [55]: red_duck.color
Out[55]: 'red'

2
Przepraszam, ale to źle. Nazwana krotka obsługuje również te: red_duck[0]lub len(red_duck)lub for x in red_duck: print(x). Ponadto nazwane krotki są niezmienne, więc te operacje zakończą się niepowodzeniem: red_duck[0] = 2, red_duck.foo = 'bar'. Ponieważ są niezmienne, nazwane krotki mogą być używane jako dictklucze.
Denilson Sá Maia,

Tak, to podstawy.
Rachunek

1
@JawSaw Nie, to nie są „podstawy”. Krotki nazwane obsługują zupełnie inny zestaw funkcji niż zwykłe klasy. Chociaż w istocie krotki nazwane są klasami, nie oznacza to, że klasy są krotkami nazwanymi.
connectyourcharger
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.