Python: как написать декоратор typing.overload для аргументов типа bool по значению

Ниже приведен пример кода того, что я пытаюсь задать.
Ни один из примеров в Интернете не пытается перегрузить значение аргумента как таковое.
Один из аргументов - это значение типа bool, и я хочу перегрузить метод, основанный на значении bool, а не на обычном типе аргумента.

from typing import overload, Union

@overload
def myfunc(arg:bool=True)-> str: ...

@overload
def myfunc(arg:bool=False)-> int: ...

def myfunc(arg:bool)->Union[int, str]:
    if arg: return "something"
    else: return 0

Правильный ли код перегрузки в приведенном выше примере кода?
Можете ли вы привести пример / блог / источник, в котором упоминается такая перегрузка, поскольку я не смог найти ничего в документах Python и pep-484

Я нашел один из возможных способов сделать это с помощью typing.Literalкак используется в последних документах python (начиная с python v3.8)

from typing import overload, Union, Literal

@overload
def myfunc(arg:Literal[True])-> str: ...

@overload
def myfunc(arg:Literal[False])-> int: ...

def myfunc(arg:bool)->Union[int, str]:
    if arg: return "something"
    else: return 0

Но я пока не могу перейти на python 3.8, так как работаю над производственным кодом, который все еще находится на python 3.6, который скоро обновится до 3.7 в лучшем случае.
Следовательно, я все еще ищу ответы о том, как этого добиться в python 3.6.

2 ответа

Решение

Установите модуль typing-extensions, который содержит официальные резервные копии различных конструкций типизации. Затем выполните:

from typing import overload, Union

# typing_extensions defines Literal for Python 3.7 and earlier, but
# re-exports it from 'typing' for later versions of Python.
from typing_extensions import Literal

@overload
def myfunc(arg: Literal[True]) -> str: ...

@overload
def myfunc(arg: Literal[False]) -> int: ...

@overload
def myfunc(arg: bool) -> Union[str, int]: ...

def myfunc(arg: bool) -> Union[int, str]:
    if arg: return "something"
    else: return 0

См. Первый пример в документации mypy по типам литералов, чтобы узнать, почему я включил третью перегрузку в bool.

Отталкиваясь от правильного принятого ответа , @overloading для аргументов по умолчанию (ключевое слово) может быть достигнуто следующим образом:

      from typing import overload, Union, Literal

@overload
def myfunc(arg: Literal[True] = True) -> str: ...

@overload
def myfunc(arg: Literal[False]) -> int: ...

def myfunc(arg: bool =  True) -> Union[int, str]:
    if arg: return "something"
    else: return 0

Первая перегрузка (с Literal[True]) используется для вызовов функций проверки типов myfunc(True) а также myfunc(), а вторая перегрузка (с Literal[False]) используется для проверки типов при вызове функции myfunc(False).

Другие вопросы по тегам