Jak opisywać typy wielu zwracanych wartości?


111

Jak używać wskazówek dotyczących typów w celu dodania adnotacji do funkcji, która zwraca an, Iterablektóra zawsze zwraca dwie wartości: a booli a str? Wskazówka Tuple[bool, str]jest bliska, z tą różnicą, że ogranicza typ wartości zwracanej do krotki, a nie do generatora lub innego typu iterowalnego.

Jestem głównie ciekawy, ponieważ chciałbym dodać adnotację do funkcji, foo()która jest używana do zwracania wielu wartości, takich jak ta:

always_a_bool, always_a_str = foo()

Zwykle funkcje takie jak foo()wykonaj coś podobnego return a, b(co zwraca krotkę), ale chciałbym, aby wskazówka dotycząca typu była wystarczająco elastyczna, aby zastąpić zwróconą krotkę generatorem lub listą lub czymś innym.



3
@ StevenM.Vascellaro To nie jest duplikat tego pytania
TWR Cole

Odpowiedzi:


159

Zawsze zwracasz jeden obiekt; używanie return one, twopo prostu zwraca krotkę.

Więc tak, -> Tuple[bool, str]jest całkowicie poprawne.

TylkoTuple typ pozwala określić stałą liczbę elementów, z których każdy odrębny typ. Naprawdę powinieneś zawsze zwracać krotkę, jeśli twoja funkcja generuje stałą liczbę zwracanych wartości, zwłaszcza gdy te wartości są specyficznymi, odrębnymi typami.

Oczekuje się, że inne typy sekwencji będą miały jedną specyfikację typu dla zmiennej liczby elementów, więc typing.Sequencenie jest tutaj odpowiedni. Zobacz też Jaka jest różnica między listami a krotkami?

Krotki są heterogenicznymi strukturami danych (tj. Ich wpisy mają różne znaczenia), podczas gdy listy są jednorodnymi sekwencjami. Krotki mają strukturę, listy mają porządek.

System podpowiedzi typu Pythona jest zgodny z tą filozofią, obecnie nie ma składni, która określałaby iterowalność o stałej długości i zawierającą określone typy w określonych pozycjach.

Jeśli musisz określić, że jakikolwiek iterowalny będzie wystarczający, najlepsze, co możesz zrobić, to:

-> Iterable[Union[bool, str]]

w którym momencie wywołujący może oczekiwać wartości logicznych i łańcuchów w dowolnej kolejności i o nieznanej długości (od 0 do nieskończoności).


2
Specyfikacja języka pozwala na zwrócenie innych iterowalnych; foo()mógł yield True; yield "blah"i a, b = foo()nadal działał. Albo foo()może zwrócić listę. Przeformułowałem moje pytanie, aby było jasne, że interesuje mnie wskazanie arbitralnej iteracji, a nie krotki.
Richard Hansen

2
@RichardHansen: Sprawdziłem ponownie PEP i dokumentację typingoraz mypykolejne 2 razy od wysłania; Jestem przekonany, że niczego nie przegapiłem. To powiedziawszy, jest tu kilku stałych bywalców SO z dużą ilością podpowiedzi typu Python, którzy nie zawahają się mnie poprawić, jeśli okażą się błędni, lub opublikują lepszą odpowiedź.
Martijn Pieters

21
Musiałem dodać, from typing import Tupleaby adnotacja krotka działała.
PHPirate

3
@PHPirate: tak, i musiałbyś zrobić to samo dla Iterablei Union. Ponieważ omawiamy tutaj ich konkretne zastosowanie, import jest implikowany.
Martijn Pieters

6
@MartijnPieters, dziękuję za świetną odpowiedź, ale myślę, że komentarz PHPirate warto edytować w oryginalnej odpowiedzi.
Tim Mironov
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.