Cag*_*ury 2 python overloading type-hinting python-3.x
假设我有一堂这样的课:
class myclass:
def __init__ (self, param1: Tuple[str,...], param2: bool) -> None:
self.member1 = param1
self.member2 = param2
self.member3 = 10
def gimmie(self) -> int | Tuple[str,...]:
return self.member1 if self.member2 else self.member3
Run Code Online (Sandbox Code Playgroud)
有什么方法可以确保 gimmie 的返回不是类型而是int | Tuple[str,...]
orint
类型 Tuple[str,...]
?
编辑:
有几个答案涉及到重要的杂技来做到这一点,而我真正想做的只是cast
返回。因此,每个答案都对代码“气味”进行了评论。
问题很简单,我构造了一个带有标志的对象,并且其中一个方法根据该标志返回两种类型中的一种。如果这是糟糕的设计,那么“正确”的方法是什么?
这是使用泛型解决此问题的方法:
from __future__ import annotations
from typing import overload, Literal, Generic, TypeVar, cast
T = TypeVar('T')
class myclass(Generic[T]):
member1: tuple[str, ...]
member2: bool
member3: int
@overload
def __init__(self: myclass[tuple[str, ...]], param1: tuple[str, ...], param2: Literal[True]) -> None:
...
@overload
def __init__(self: myclass[int], param1: tuple[str, ...], param2: Literal[False]) -> None:
...
def __init__(self, param1: tuple[str, ...], param2: bool) -> None:
self.member1 = param1
self.member2 = param2
self.member3 = 10
def gimmie(self) -> T:
return cast(T, self.member1 if self.member2 else self.member3)
reveal_type(myclass(('a', 'b'), True).gimmie())
# note: Revealed type is "builtins.tuple*[builtins.str]"
reveal_type(myclass(('a', 'b'), False).gimmie())
# note: Revealed type is "builtins.int*"
Run Code Online (Sandbox Code Playgroud)
一些注意事项:
self
参数以赋予其不同的静态类型。通常,我们不会注释self
,所以请确保不要忘记这一点!a if b else c
如果不添加cast
.我确实同意 Samwise 的观点,即这种类型的柔道是一种代码味道,并且可能隐藏了项目设计的问题。