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)
.