Dans python 3.x, il est courant d'utiliser l'annotation de type retour d'une fonction, telle que:
def foo() -> str:
return "bar"
Quelle est l'annotation correcte pour le type "void"?
J'envisage 3 options:
def foo() -> None:
None
n'est pas un type,def foo() -> type(None):
NoneType
,def foo():
L'option 2. me semble la plus logique, mais j'ai déjà vu quelques exemples de 1.
Ceci est directement de la documentation PEP 484 - Type Hints :
Lorsqu'elle est utilisée dans une indication de type, l'expression
None
est considérée comme équivalente àtype(None)
.
Et, comme vous pouvez le voir, la plupart des exemples utilisent None
comme type de retour.
TLDR: L'équivalent idiomatique d'une annotation de type de retour void
est -> None
.
def foo() -> None:
pass
Indication de type dans Python ne nécessite pas strictement les types réels. Par exemple, les annotations peuvent utiliser des chaînes de noms de type: Union[str, int]
, Union[str, 'int']
, 'Union[str, int]'
et différentes variantes sont équivalentes.
De même, l'annotation de type None
est considérée comme signifiant "est de NoneType
". Cela peut être utilisé non seulement pour les types de retour, mais vous le verrez le plus souvent ici:
bar : None
def foo(baz: None) -> None:
return None
Cela s'applique également aux types génériques. Par exemple, vous pouvez utiliser None
dans Generator[int, None, None]
Pour indiquer qu'un générateur ne prend pas ou ne renvoie pas de valeurs.
Même si PEP 484 suggère que None
signifie type(None)
, vous ne devez pas utiliser ce dernier formulaire explicitement. La spécification d'indication de type ne comprend pas aucune forme de type(...)
. Il s'agit techniquement d'une expression d'exécution, et sa prise en charge dépend entièrement du vérificateur de type. Le projet mypy
est envisageant de supprimer le support pour type(None)
et le supprime également de 484.
Ou peut-être devrions-nous mettre à jour PEP 484 pour ne pas suggérer que
type(None)
est valide en tant que type, etNone
est la seule orthographe correcte? Il devrait y avoir une - et de préférence une seule - manière évidente de le faire, etc.
L'équivalent statique de "le type de X" est Type[X]
. Ceci est également valable pour None
:
def foo() -> Type[None]:
pass
Cependant, c'est essentiellement l'équivalent de Type[True]
Et similaire. Il élimine un cas spécial (utilisation d'une valeur au lieu d'un type) avec un autre cas spécial (utilisation d'un type dérivé d'une valeur). Le cas particulier idiomatique est d'utiliser simplement None
.
L'omission du type de retour ne signifie pas qu'il n'y a pas de valeur de retour. Selon PEP 484 :
Pour une fonction cochée, l'annotation par défaut pour les arguments et pour le type de retour est
Any
.
Cela signifie que la valeur est considérée comme typée dynamiquement et statiquement prend en charge toute opération . C'est pratiquement le sens opposé de void
.