web-dev-qa-db-fra.com

Comment spécifier un type de retour "nullable" avec des indicateurs de type

Supposons que j'ai une fonction:

def get_some_date(some_argument: int=None) -> %datetime_or_None%:
    if some_argument is not None and some_argument == 1:
        return datetime.utcnow()
    else:
        return None

Comment spécifier le type de retour pour quelque chose qui peut être None?

113
exfizik

Vous recherchez Optional .

Étant donné que votre type de retour peut être datetime (comme renvoyé de datetime.utcnow()) ou None, vous devez utiliser Optional[datetime]:

from typing import Optional

def get_some_date(some_argument: int=None) -> Optional[datetime]:
    # as defined

Dans la documentation sur la frappe, Optional est un raccourci pour:

Optional[X] est équivalent à Union[X, None].

Union[X, Y] signifie une valeur de type X ou Y.


Si vous voulez être explicite à cause des craintes que d'autres puissent trébucher sur Optional et ne pas vous rendre compte de sa signification, vous pouvez toujours utiliser Union:

from typing import Union

def get_some_date(some_argument: int=None) -> Union[datetime, None]:

Mais je doute que ce soit une bonne idée, Optional est un nom indicatif et permet d’économiser quelques frappes de touche.

Comme indiqué dans les commentaires de @ Michael0x2a, Union[T, None] est transformé en Union[T, type(None)], il n'est donc pas nécessaire d'utiliser type ici.

Visuellement, ils peuvent différer mais par programmation, dans les deux cas, le résultat est exactement le même ; Union[datetime.datetime, NoneType] sera le type enregistré dans get_some_date.__annotations__*:

>>> from typing import get_type_hints
>>> print(get_type_hints(get_some_date))
{'return': typing.Union[datetime.datetime, NoneType],
 'some_argument': typing.Union[int, NoneType]}

*Utilisez typing.get_type_hints pour saisir l'attribut '__annotations__' des objets au lieu d'y accéder directement.

178