Как указать тип возвращаемого значения «nullable» с подсказками типа

177

Предположим, у меня есть функция:

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

Как мне указать тип возвращаемого значения для чего-то, что может быть None?

exfizik
источник

Ответы:

279

Ты ищешь Optional.

Поскольку ваш тип возврата может быть datetime(как возвращено из datetime.utcnow()) или Noneвы должны использовать Optional[datetime]:

from typing import Optional

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

Из документации о наборе текста Optionalесть сокращение для:

Optional[X]эквивалентно Union[X, None].

где Union[X, Y]означает значение типа Xили Y.


Если вы хотите быть откровенным из-за опасений, на которые могут наткнуться другие Optionalи не осознающих его смысла, вы всегда можете использовать Union:

from typing import Union

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

Но я сомневаюсь, что это хорошая идея, Optionalэто ориентировочное имя, и оно спасает пару нажатий клавиш.

Как указано в комментариях @ Michael0x2a преобразуется Union[T, None]в Union[T, type(None)]так что нет необходимости использовать typeздесь.

Визуально они могут отличаться, но программно, в обоих случаях результат абсолютно одинаков ; Union[datetime.datetime, NoneType]будет тип хранится в 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]}

* Используйте, typing.get_type_hintsчтобы захватить __annotations__атрибут объекта вместо прямого доступа к нему.

Димитрис Фасаракис Хиллиард
источник
10
Вы можете упростить Union[datetime, type(None)]до Union[datetime, None]- согласно PEP 484 , использование Noneвнутри аннотации типа всегда рассматривается как эквивалентное type(None). ( typingДокументация фактически использует Noneв большинстве случаев, но не здесь, что является недосмотром).
Michael0x2a
@ Michael0x2a не знал этого, интересно. Добавил это :)
Димитрис Фасаракис Хиллиард
4
Я пошел вперед и представил патч, чтобы исправить это только сейчас, так что, надеюсь, документы будут более последовательными об этом в ближайшем будущем!
Michael0x2a
1
Optional[T]Типа хорошо известен в сообществе функционального программирования. Читатель не только узнает, что это означает Union[T, None], но также распознает шаблон использования, который функция должна возвращать None, если нет значимого ответа, есть ошибка или результат не найден.
недельная