Какую подсказку типа указать, когда функция возвращает либо объект определенного типа, либо None?

С тех пор, как я обнаружил подсказки типов в Python, я начал их использовать, так как считаю, что они полезны для читателя кода. Я ожидаю, что в будущем эти подсказки типов в конечном итоге станут средствами статической проверки типов, потому что это сделает код намного более надежным, а это очень важно для серьезного проекта.

Кроме того, у меня есть много функций, в которых тип возвращаемого значения может быть либо BSTNode, либо None. Например, это может быть None, потому что в функции поиска, если BSTNode не найдено, просто возвращается None. Есть ли способ указать, что возвращаемый тип также может быть None?

В настоящее время я использую что-то вроде следующего

def search(self, x) -> BSTNode:
    pass

Я знаю, что могу использовать строки в качестве подсказок типа, но я не уверен, что это правильный или лучший способ сделать это.

def search(self, x) -> "BSTNode | None":
    pass

person nbro    schedule 20.02.2016    source источник


Ответы (2)


В Python до версии 3.10 конвейер не имеет особого значения в подсказках строкового типа. Таким образом, в Python ≤ 3.9 я бы придерживался способов PEP 0484. документы для типов объединения:

Либо

from typing import Union

def search(self, x) -> Union[BSTNode, None]:
    pass

или, более кратко, но эквивалентно

from typing import Optional

def search(self, x) -> Optional[BSTNode]:
    pass

В Python ≥ 3.10 вы действительно можете использовать | для создания представлений объединения типов даже без кавычек. См. ответ Жана Моне, PEP 604 -- Разрешить запись типов объединения как X | Y, Что нового В Python 3.10 или документация Python 3.10 нового types.Union введите для подробностей.

person das-g    schedule 20.02.2016
comment
Хорошо, спасибо, что указали и на документы. Однако тот факт, что мне нужно будет импортировать Union или Optional в каждый модуль, является аферой. Честно говоря, я тоже использую подсказки типов только потому, что они, по-видимому, являются частью ядра языка (Python 3.5). - person nbro; 20.02.2016
comment
Такова природа стандартной библиотеки Python. Большая часть его содержимого находится в пространстве имен. И по уважительным причинам. Пространства имен — это отличная идея — давайте сделаем больше таких! - person das-g; 20.02.2016
comment
Пространства имен хороши во многих случаях, но я ожидал, что эта функция станет частью ядра языка... - person nbro; 20.02.2016
comment
Это своего рода. Но это значительно недавняя функция, поэтому вероятность того, что пользовательский код уже определяет имена Union или Optional, не является незначительной и должна учитываться. - person das-g; 20.02.2016
comment
Я обновил свой ответ, чтобы отразить изменения в Python 3.10, в котором представлена ​​эта самая функция/синтаксис для типов Union. - person das-g; 28.04.2021

Благодаря PEP 604 можно использовать нотацию | канала. , эквивалентно Union:

def func() -> int | None:
    ...
my_var: int | None = None

# same as

from typing import Optional, Union

def func() -> Optional[int]:
    ...
def func() -> Union[int, None]:
    ...
my_var: Optional[int] = None
my_var: Union[int, None] = None

Эта функция представлена ​​в Python 3.10, но вы можете начать использовать ее в Python 3.8 и 3.9 (не уверены в 3.7?), импортировав аннотации в начало файла:

from __future__ import annotations
person Jean Monet    schedule 27.04.2021