Comment spécifier plusieurs types de retour à l'aide de conseils de type

205

J'ai une fonction en python qui peut retourner un boolou un list. Existe-t-il un moyen de spécifier les types de retour à l'aide d'indices de type.

Par exemple, est-ce la bonne façon de procéder?

def foo(id) -> list or bool:
      ...
Yahya Uddin
la source
5
comment vous retrouvez-vous avec une liste ou un booléen?
Padraic Cunningham
11
@PadraicCunningham Peut-être que l'implémentation est que je vous enverrai mon identifiant, vous m'envoyez soit une liste soit un booléen : D
Bhargav Rao
c'est probablement une implémentation faible
Sławomir Lenart
@PadraicCunningham Polymorphism. Si votre fonction vérifie l'entrée, quelle qu'elle soit, vous voulez obtenir un booléen lorsque vous alimentez une variable ou obtenir une liste de booléens lorsque vous alimentez une liste de variables.
Guimoute

Réponses:

282

De la documentation

classe typing.Union

Type d'union; Union [X, Y] signifie X ou Y.

Par conséquent, la bonne façon de représenter plus d'un type de données de retour est

from typing import Union


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

Mais notez que la saisie n'est pas appliquée. Python continue de rester un langage à typage dynamique. La syntaxe d'annotation a été développée pour aider lors du développement du code avant sa mise en production. Comme l'indique PEP 484, "aucune vérification de type ne se produit lors de l'exécution".

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

Comme vous pouvez le voir, je passe une valeur int et retourne une chaîne. Cependant, le __annotations__sera réglé sur les valeurs respectives.

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

Veuillez consulter le PEP 483 pour en savoir plus sur les astuces de type. Voir également Que sont les conseils de type dans Python 3.5 ?

Veuillez noter que cela n'est disponible que pour Python 3.5 et versions ultérieures. Ceci est clairement mentionné dans le PEP 484 .

Bhargav Rao
la source
Y a-t-il un équivalent en Python 3.4
Yahya Uddin
1
@YahyaUddin Nope - PEP 484 : '(.... Ce n'est que pour Python3.5 vers le haut.
Bhargav Rao
1
@YahyaUddin Assez surprenant. Voulez-vous dire les annotations de fonction par hasard?
Bhargav Rao
2
Alors laissez-moi voir si je l'ai. Python 3.4 a des annotations de fonction qui ne font rien d'autre que d'annoter qui n'est PAS appliqué. Mais dans Python 3.5, il s'agit d'une vérification de type réelle.
Yahya Uddin
1
@BhargavRao, désolé pour ça! Je pensais juste qu'il était trop important de laisser dans la section des commentaires.
Bobort
26

La déclaration def foo(client_id: str) -> list or bool: lorsqu'elle est évaluée, équivaut à def foo(client_id: str) -> list:et ne fera donc pas ce que vous voulez.

La manière native de décrire un indice de type "A ou B" est Union (merci à Bhargav Rao):

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

Je ne veux pas être le gars "Pourquoi voulez-vous faire ça quand même", mais peut-être que 2 types de retours ne sont pas ce que vous voulez:

Si vous souhaitez renvoyer un booléen pour indiquer un certain type de cas d'erreur spécial, envisagez d'utiliser des exceptions à la place. Si vous souhaitez renvoyer un bool en tant que valeur spéciale, une liste vide serait peut-être une bonne représentation. Vous pouvez également indiquer qui Nonepourrait être retourné avecOptional[list]

Felk
la source
6
Il existe des utilisations dans lesquelles le retour de plusieurs types peut être ce que vous voulez: par exemple, si vous devez renvoyer l'un d'un ensemble de sous-types, mais pas d'autres sous-types, ou si vous essayez de traiter des données et que vous souhaitez renvoyer le formulaire brut si le traitement n'est pas pas disponible. De plus, si vous encapsulez du code hérité, il peut être très utile, car il facilite le processus de mise à niveau et / ou détecte les endroits difficiles.
Nathaniel Ford
L'idée d'exceptions et de liste vide a également été utile. merci
Yahya Uddin
20

Au cas où quelqu'un atterrirait ici à la recherche de "comment spécifier les types de valeurs de retour multiples?", Utilisez Tuple[type_value1, ..., type_valueN]

from typing import Tuple

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

Plus d'informations: https://code-examples.net/en/q/2651e60

Anton Khodak
la source