通用类型别名WRT通用类参数

发布于 2025-02-12 10:32:10 字数 1944 浏览 0 评论 0 原文

根据 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文