根据 mypy支持使用通用 typevar
在类型的别名中,例如,
T = TypeVar("T")
Alias = Tuple[int, T]
def f(t: T) -> Alias[T]:
return (1, t)
f('x')
我想知道这是否扩展到类。具体来说,要帮助这种模式:
T = TypeVar("T")
U = TypeVar("U")
V = TypeVar("V")
W = TypeVar("W")
class Bar(Generic[T, U, V]): ...
class Foo(Generic[T, U, V, W]):
def do_something(self, x: Bar[T, U, V], y: W) -> Bar[T, U, V]:
reveal_type(x) # note: Revealed type is "Bar[T`1, U`2, V`3]"
有点人为,但要点是, foo
在高度参数化的 bar
上执行许多操作,不必不必去重复 bar [t,u,v]
到处都是(尤其是因为在实际代码中,typevars具有长名称)。
我尝试制作 classVar [typealias]
,但我认为这实际上不起作用,并且仅替换了任何
,我只看到链接的mypy文档中功能的示例:
class Foo(Generic[T, U, V, W]):
BarType: ClassVar[TypeAlias] = Bar[T, U, V] # Had hoped this would work, but seems to evaluate to just be `Any`
def do_something(self, x: BarType) -> BarType:
reveal_type(x) # note: Revealed type is "Any"
我还尝试使用中间类型Var:
BarType = TypeVar("BarType", bound=Bar[Any, Any, Any])
class Foo(Generic[BarType, W]):
def do_something(self, x: BarType, y: W) -> BarType:
reveal_type(x) # BarType
但是我在这里讨论了一些问题使用与typevar一起使用typevar的类别从另一个通用类绑定,所以我仍然不确定这是要走的路。此外,在现实生活代码中, foo
实际上需要访问 bar
的各个参数,因此类签名需要为(我假设)
class Foo(Generic[T, U, V, BarType, W]): ...
:例如,该类看起来有些怪异,例如,
Foo[int, int, str, Bar[int, int, str], float]
我尚不清楚Mypy是否会在参数的两个分组 t,u,u,v
中抓住不一致。
According to https://mypy.readthedocs.io/en/stable/generics.html#generic-type-aliases mypy supports using a generic TypeVar
in an type alias, e.g.
T = TypeVar("T")
Alias = Tuple[int, T]
def f(t: T) -> Alias[T]:
return (1, t)
f('x')
I wondered if this extended to classes. Specifically, to help with this pattern:
T = TypeVar("T")
U = TypeVar("U")
V = TypeVar("V")
W = TypeVar("W")
class Bar(Generic[T, U, V]): ...
class Foo(Generic[T, U, V, W]):
def do_something(self, x: Bar[T, U, V], y: W) -> Bar[T, U, V]:
reveal_type(x) # note: Revealed type is "Bar[T`1, U`2, V`3]"
A bit contrived, but the point is, Foo
performs lots of operations on a highly parametrized Bar
and it would be nice to not have to repeat Bar[T, U , V]
everywhere (especially because in the real code the TypeVars have long names).
I tried making a ClassVar[TypeAlias]
, but I don't think this actually worked and just substituted Any
, and I only see examples for functions in the linked mypy docs:
class Foo(Generic[T, U, V, W]):
BarType: ClassVar[TypeAlias] = Bar[T, U, V] # Had hoped this would work, but seems to evaluate to just be `Any`
def do_something(self, x: BarType) -> BarType:
reveal_type(x) # note: Revealed type is "Any"
I also tried using an intermediate TypeVar:
BarType = TypeVar("BarType", bound=Bar[Any, Any, Any])
class Foo(Generic[BarType, W]):
def do_something(self, x: BarType, y: W) -> BarType:
reveal_type(x) # BarType
But I had some issues discussed here Genericizing a class using a TypeVar with a bound from another generic class so I am still unsure if this is the way to go. Furthermore, in the real life code, Foo
actually needs access to the individual parameters of Bar
, so the class signature would need to be (I assume):
class Foo(Generic[T, U, V, BarType, W]): ...
which would make instantiating the class look a bit weird, e.g.,
Foo[int, int, str, Bar[int, int, str], float]
and it's not clear to me yet whether mypy would catch inconsistencies in the two groupings of the parameters T, U, V
.
发布评论