Jak określić wiele typów zwrotów za pomocą wskazówek typu

204

Mam w Pythonie funkcję, która może zwrócić a boollub a list. Czy istnieje sposób na określenie typów zwrotów za pomocą podpowiedzi typu.

Na przykład, czy jest to właściwy sposób, aby to zrobić?

def foo(id) -> list or bool:
      ...
Yahya Uddin
źródło
5
jak skończysz z listą lub wartością logiczną?
Padraic Cunningham
11
@PadraicCunningham Być może realizacja polega na tym, że wyślę ci mój identyfikator, wyślesz mi listę albo wartość logiczną : D
Bhargav Rao
prawdopodobnie jest to słaba implementacja
Sławomir Lenart
@PadraicCunningham Polymorphism. Jeśli twoja funkcja sprawdza dane wejściowe, cokolwiek to jest, chcesz uzyskać wartość logiczną, gdy podajesz jedną zmienną, lub listę booleanów, gdy podajesz listę zmiennych.
Guimoute

Odpowiedzi:

281

Z dokumentacji

klasa typing.Union

Typ Unii; Związek [X, Y] oznacza X lub Y.

Dlatego właściwym sposobem reprezentowania więcej niż jednego zwracanego typu danych jest

from typing import Union


def foo(client_id: str) -> Union[list,bool]

Pamiętaj jednak, że pisanie nie jest wymuszone. Python nadal pozostaje językiem o dynamicznym pisaniu. Składnia adnotacji została opracowana, aby pomóc podczas opracowywania kodu przed udostępnieniem go do produkcji. Jak stwierdza PEP 484, „sprawdzanie typu nie zachodzi w czasie wykonywania”.

>>> def foo(a:str) -> list:
...     return("Works")
... 
>>> foo(1)
'Works'

Jak widać, przekazuję wartość int i zwracam str. Jednak __annotations__zostaną ustawione na odpowiednie wartości.

>>> foo.__annotations__ 
{'return': <class 'list'>, 'a': <class 'str'>}

Proszę przejrzeć PEP 483, aby uzyskać więcej informacji na temat podpowiedzi typu. Zobacz także Co to są wskazówki dotyczące typów w Python 3.5 ?

Należy pamiętać, że jest to dostępne tylko dla języka Python 3.5 i nowszych wersji. Jest to wyraźnie wspomniane w PEP 484 .

Bhargav Rao
źródło
Czy istnieje odpowiednik w Pythonie 3.4
Yahya Uddin
1
@YahyaUddin Nope - PEP 484 : „(.... Dotyczy tylko Python 3.5 w górę.
Bhargav Rao
1
@YahyaUddin Całkiem zaskakujące. Czy chodziło Ci o Adnotacje funkcyjne przez przypadek?
Bhargav Rao
2
Pokaż mi, czy to dostałem. Python 3.4 ma adnotacje funkcyjne, które nie robią nic poza adnotacjami, które NIE są wymuszane. Ale w Python 3.5 jest to sprawdzanie rzeczywistego typu.
Yahya Uddin
1
@BhargavRao, przepraszam za to! Po prostu czułem, że zbyt ważne jest, aby pozostawić je w sekcji komentarzy.
Bobort
26

Oświadczenie def foo(client_id: str) -> list or bool:po ocenie jest równoważne def foo(client_id: str) -> list:i dlatego nie zrobi tego, co chcesz.

Rodzimym sposobem opisu wskazówki typu „A lub B” jest Union (dzięki Bhargav Rao):

def foo(client_id: str) -> Union[list, bool]:

Nie chcę być facetem „Dlaczego i tak to robić”, ale być może 2 typy zwrotów nie są tym, czego chcesz:

Jeśli chcesz zwrócić wartość bool wskazującą na jakiś szczególny przypadek błędu, rozważ użycie wyjątków. Jeśli chcesz zwrócić wartość bool jako jakąś specjalną wartość, być może pusta lista byłaby dobrą reprezentacją. Możesz również wskazać, że Nonemożna go zwrócićOptional[list]

Felk
źródło
6
Istnieją zastosowania, w których zwracanie wielu typów może być tym, czego chcesz: na przykład, jeśli musisz zwrócić jeden z niektórych zestawów podtypów, ale nie innych podtypów, lub jeśli próbujesz przetwarzać dane i chcesz zwrócić postać surową, jeśli przetwarzanie nie jest przetwarzane dostępne. Ponadto, jeśli pakujesz starszy kod, może to być bardzo przydatne, ponieważ pomaga w procesie aktualizacji i / lub wyświetlać niewygodne miejsca.
Nathaniel Ford
Pomocny był także wyjątek i pomysł pustej listy. dzięki
Yahya Uddin
20

Jeśli ktoś wylądował tutaj w poszukiwaniu „jak określić typy wielu zwracanych wartości?”, Użyj Tuple[type_value1, ..., type_valueN]

from typing import Tuple

def f() -> Tuple[dict, str]:
    a = {1: 2}
    b = "hello"
    return a, b

Więcej informacji: https://code-examples.net/en/q/2651e60

Anton Khodak
źródło