这是一个老问题.原因是您在这两个分支中都指定了默认值,因此在这两个分支中都可以使用x()
,并且返回类型未定义.
对于这种情况,我有以下模式:
from typing import overload, Literal
@overload
def x(a: int = 5, t: Literal[True] = True, b: int = 5) -> int: ...
@overload
def x(a: int = 5, *, t: Literal[False], b: int = 5) -> str: ...
@overload
def x(a: int, t: Literal[False], b: int = 5) -> str: ...
def x(a: int = 5, t: bool = True, b: int = 5) -> int | str:
if t:
return 5
return "asd"
为什么,如何?你必须考虑调用函数的方法.首先,你可以提供a
,然后t
可以作为kwarg(#2)或arg(#3)给出.你也可以保留a
个默认值,那么t
总是一个kwarg(#2).这是为了防止把arg放在kwarg后面,kwarg是SyntaxError
.在多个参数上重载比较困难,但也可能是这样:
@overload
def f(a: int = 1, b: Literal[True] = True, c: Literal[True] = True) -> int: ...
@overload
def f(a: int = 1, *, b: Literal[False], c: Literal[True] = True) -> Literal['True']: ...
@overload
def f(a: int = 1, *, b: Literal[False], c: Literal[False]) -> Literal['False']: ...
@overload
def f(a: int, b: Literal[False], c: Literal[True] = True) -> Literal['True']: ...
@overload
def f(a: int, b: Literal[False], c: Literal[False]) -> Literal['False']: ...
def f(a: int = 1, b: bool = True, c: bool = True) -> int | Literal['True', 'False']:
return a if b else ('True' if c else 'False') # mypy doesn't like str(c)
你可以玩超载here.