`TypeVar`:参数类型作为“bound”参数的值

问题描述 投票:0回答:1

我想实现一个像这样的通用类:

S = TypeVar("S")
T = TypeVar("T", bound=OtherParametrizedClass)

class MyClass(Generic[T[S]]):
    def some_method(param: S) -> None:
        pass

我已经尝试过以下方法:

S = TypeVar("S")
T = TypeVar("T", bound=OtherParametrizedClass)

class MyClass(Generic[S, T[S]]):
    def some_method(param: S) -> None:
        pass
    def other_method(param: T) -> None:
        pass

它与 MyPy 一起按预期工作。然而,当Python解释器运行这段代码时,它给出了以下错误:

TypeError: 'TypeVar' object is not subscriptable.

我发现,这意味着

TypeVar
没有实现
[]
运算符。

有人知道如何获得同时满足 mypy 和 Python 解释器的解决方案吗?

编辑: 我还尝试过以下方法:

S = TypeVar("S")
T = TypeVar("T", bound=OtherParametrizedClass[S])

class MyClass(Generic[T]):
    def some_method(param: S) -> None:
        pass
    def other_method(param: T) -> None:
        pass

Python 解释器不会给出任何错误/警告。然而 mypy 抱怨第二行:

Invalid type "S"
python generics mypy python-typing higher-kinded-types
1个回答
-2
投票

我不确定我是否完全理解您想要实现的目标。

基本上有两个问题:

  • 为什么需要定义
    T
  • 为什么是
    MyClass
    Generic[T]
    而不是
    Generic[S]

第二个问题是关键:我认为从根本上来说,你犯的错误是你试图制作

MyClass
Generic[T]
,而它应该只是
Generic[S]
,此时你甚至不需要定义
T
other_method
可以直接返回
OtherParametrizedClass[S]

下面是我认为可以实现您想要实现的目标的示例:

import dataclasses
from typing import Generic, TypeVar

N = TypeVar("N", int, float)


@dataclasses.dataclass
class Adder(Generic[N]):
    to_add: N

    def add(self, value: N) -> N:
        return value + self.to_add


class Foo(Generic[N]):
    def get_adder(self, to_add: N) -> Adder[N]:
        return Adder(to_add)

从我的示例到您的示例的名称映射:

  • N
    S
  • Adder
    OtherParametrizedClass
  • Foo
    MyClass
  • Foo.get_adder
    MyClass.other_method
© www.soinside.com 2019 - 2024. All rights reserved.