Puisque python est typé dynamiquement, nous pouvons bien sûr faire quelque chose comme ceci:
def f(x):
return 2 if x else "s"
Mais est-ce la façon dont python était réellement destiné à être utilisé? Ou en d'autres termes, les types d'unions existent-ils dans le sens qu'ils font dans Racket par exemple? Ou les utilisons-nous uniquement comme ceci:
def f(x):
if x:
return "s"
où la seule "union" dont nous avons besoin est avec None?
La saisie par union n'est nécessaire que si vous disposez d'un langage typé statiquement, car vous devez déclarer qu'un objet peut renvoyer un type parmi plusieurs (dans votre cas, un int
ou str
, ou dans l'autre exemple str
ou NoneType
).
Python ne traite que des objets , il n'est donc jamais nécessaire de considérer les "types d'union". Python renvoient ce qu'elles renvoient, si le programmeur veut retourner différents types pour des résultats différents, alors c'est leur choix. Le choix est alors un choix d'architecture, et ne fait aucune différence pour le Python (il n'y a donc rien à "comparer" ici).
Python 3.5 introduit une norme pour la création d'indices de type facultatif , et cette norme comprend Union[...]
et Optional[...]
annotations.
le type lui-même n'existe pas parce que Python est juste un langage typé dynamiquement, cependant, dans les versions plus récentes Python, Union Type est une option pour Type Hinting ,
from typing import Union,TypeVar
T = TypeVar('T')
def f(x: T) -> Union[str, None]:
if x:
return "x"
vous pouvez l'utiliser pour annoter votre code, permettant ainsi la vérification de la syntaxe au niveau IDE/Editor.
Voici quelques options pour traiter les cas d'utilisation où vous avez besoin d'un type union/sum étiqueté en Python:
Enum + Tuples
from enum import Enum
Token = Enum('Token', ['Number', 'Operator', 'Identifier', 'Space', 'Expression'])
(Token.Number, 42) # int type
(Token.Operator, '+') # str type 1
(Token.Identifier, 'foo') # str type 2
(Token.Space, ) # no data
(Token.Expression, 'lambda', 'x', 'x+x') # multiple data
isinstance
if isinstance(token, int):
# Number type
if isinstance(token, str):
# Identifier type
sumtypes module
Bien entendu, ces approches ont toutes leurs inconvénients.
Ajout à la réponse @MartijnPieters:
Mais est-ce que la manière python était réellement destinée à être utilisée?
Renvoyer un type différent en fonction du paramètre n'est jamais une bonne pratique dans aucune langue. Cela rend les tests, la maintenance et l'extension du code vraiment difficiles et à mon humble avis est un anti-modèle (mais bien sûr parfois le mal nécessaire). Les résultats doivent au moins être liés via une interface commune.
La seule raison pour laquelle union
a été introduite dans C est le gain de performances. Mais en Python vous n'avez pas ce gain de performances en raison de la nature dynamique du langage (comme Martijn l'a remarqué). En fait, l'introduction de union
réduirait les performances puisque la taille de union
est toujours la taille du plus grand membre. Ainsi Python n'aura jamais de type C union
.