Указание nullable возвращаемого типа в Python: примеры
Быстрый ответ
В Python для задания типа, который может иметь значение None
, используйте Optional
в версиях до 3.10 или оператор |
для объединения типа с None
начиная с версии 3.10 и выше.
Показываю это на примере для версий до 3.10:
from typing import Optional
def func() -> Optional[int]:
return None # либо число 42, если вы подумали о главном вопросе жизни
Для версий, начиная с Python 3.10, воспользуйтесь таким кодом:
def func() -> int | None:
return None # или число 2, например
Подсказки типов: где и для чего их применять?
Опциональные типы служат указателями на специфику функций:
- Когда результат запроса к базе данных может быть
None
. - В процессе анализа текстовых данных, которые могут содержать неоднозначные сегменты.
- Во время работы фабрик функций, которые в определенных случаях могут возвращать
None
, когда возникают непредусмотренные обстоятельства.
Важный совет: отвественно подойдите к составлению документации, объясняющей, в каких ситуациях возвращает None
. Такой подход облегчит жизнь ваших коллег в будущем.
Погружаемся в типизацию
Воспользуйтесь функцией typing.get_type_hints
для доступа к подсказкам типов. Это окажется полезным при занятии метапрограммированием или динамическим контролем типов.
Пример использования:
from typing import get_type_hints
def func() -> int | None:
return None # или ваше любимое число
print(get_type_hints(func))
# В результате мы получим: {'return': Union[int, NoneType]}
Совет: функция get_type_hints
отлично подходит для исследования функций, это похоже на то, как если бы у вас всегда был под рукой отладчик.
Будьте внимательны к null
- Малоочевидные и недокументированные возвращаемые nullable типы могут стать корнями ошибок.
- Применяйте проверку типов, особенно в случаях с декораторами, чтобы избавиться от внезапных проблем.
Решение: Постоянно проверяйте свой код с помощью инструментов статического анализа для подсказок типов.
Визуализация
Обычные поезда : 🚂 = Не-nullable типы
Призрачные поезда: 👻🚂 = Nullable типы, которые могут быть значение None.
На языке Python это выражается так:
from typing import Optional
def get_ghost_train() -> Optional[Train]:
return train if train_arrives else None
Важно понять, что конечный тип, возвращаемый функцией, становится столь неопределенным, как и время прибытия призрачного поезда.
Union vs Optional: что предпочесть?
Для Python версий до 3.10
Optional[ReturnType]
выглядит более читаемым, чем Union[ReturnType, None]
.
Для Python 3.10 и новее
Синтаксис с оператором |
представляет собой более краткую альтернативу для Optional
.
ReturnType | None
заменяет Optional[ReturnType]
Запомните: на самом деле Optional
– это просто другой способ записи Union[ReturnType, None]
. Выбор между ними – это как спор о том, что лучше: табы или пробелы.
Работа с классами данных
Применение Optional
или оператора |
также актуально при работе с классами данных:
Пример для Python до версии 3.10:
from dataclasses import dataclass
from typing import Optional
@dataclass
class Example:
attribute: Optional[int] = None # Может отсутствовать, чтобы оставить место для неопределенности.
Для Python 3.10 и новее:
from dataclasses import dataclass
@dataclass
class Example:
attribute: int | None = None # Некогда и в математике приходится делать перерывы.
Совет: Стремление к консистенции важно для удобства поддержки и понимания кода.
Полезные материалы
- PEP 484 – Type Hints – базовый документ о системе типизации в Python.
- PEP 604 – Разрешение записи объединений типов с помощью X | Y – описание новинок в синтаксисе для nullable типов в Python 3.10+.
- Type Checking in Python (Guide) – Real Python – в этом источнике содержатся практические советы по использованию
typing.Optional
для типов, которые могут иметь значениеNone
. - Python 3.10: Cool New Features for You to Try – Real Python – обзор упрощений в Python 3.10 для типизации с
None
-значениями. - Kinds of Types – mypy 1.8.0 documentation – тут вы найдете помощь в применении
Optional
без ошибок при статической проверке черезmypy
. - PEP 557 – Data Classes – руководство по работе с аннотациями типов в data classes. Хотя и не прямо связано с nullable типами, это весьма полезное дополнение.