__init__ 类中的 TypeVar 类型提示

san*_*ers 6 python python-typing

我试图使用 TypeVar 来指示 init 参数为某种类型。但我做错了,或者根本不可能。

from typing import TypeVar

T=TypeVar("T")

class TestClass:
    def __init__(self,value:T):
        self._value=value

a = TestClass(value=10)
b = TestClass(value="abc")

reveal_type(a._value)
reveal_type(b._value)
Run Code Online (Sandbox Code Playgroud)

我希望揭露类型a._value会是int并且b._value一直是string。但它们都显示为“T`-1”

任何帮助或见解表示赞赏!

[编辑]

稍微扩展一点的例子。BaseClass 将被覆盖,实际类型提示由覆盖类提供。

from typing import TypeVar

T=TypeVar("T")

class BaseClass:
    def __init__(self,value):
        self._value = value

class Class1(BaseClass):
    def __init__(self,value:str):
        super().__init__(value)

class Class2(BaseClass):
    def __init__(self,value:int):
        super().__init__(value)

a = Class1("A value")
b = Class2(10)

reveal_type(a._value)
reveal_type(b._value)
Run Code Online (Sandbox Code Playgroud)

Mis*_*agi 8

默认情况下,使用 TypeVar 将其范围仅限于将其用作注释的方法/函数。为了将 TypeVar 的范围限定为实例和所有方法/属性,请将类声明为Generic.

from typing import TypeVar, Generic

T=TypeVar("T")

class BaseClass(Generic[T]):       # Scope of `T` is the class:
    def __init__(self, value: T):  # Providing some `T` on `__init__`
        self._value = value        # defines the class' `T`
Run Code Online (Sandbox Code Playgroud)

这允许将子类声明为通用的或具体的。

class Class1(BaseClass[str]):      # "is a" BaseClass where `T = str`
    pass  # No need to repeat ``__init__``

class ClassT(BaseClass[T]):        # "is a" BaseClass where `T = T'`
    @property
    def value(self) -> T:
        return self._value

reveal_type(Class1("Hello World")._value)  # Revealed type is 'builtins.str*'
reveal_type(Class1(b"Uh Oh!")._value)      # error: Argument 1 to "Class1" has incompatible type "bytes"; expected "str"

reveal_type(ClassT(42).value)              # Revealed type is 'builtins.int*'
Run Code Online (Sandbox Code Playgroud)