【问题标题】:TypeVar in class __init__ type hinting__init__ 类中的 TypeVar 类型提示
【发布时间】:2020-11-17 10:37:35
【问题描述】:

我正在尝试使用 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)

我希望 a._value 的显示类型是 intb._valuestring。 但它们都显示为“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)

【问题讨论】:

  • 你写这段代码的时候是什么意思?你期望类型变量做什么?这不是你使用类型变量的方式。
  • 你想让TestClass 是通用的还是什么?
  • 我基本上希望 _value 属性采用我分配给它的值的类型。但事实并非如此。
  • 您必须将TestClass 定义为泛型,即class TestClass(Generic[T]):。否则,T 的具体类型仅作用于方法并在之后丢失

标签: python python-typing


【解决方案1】:

默认情况下,使用 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`

这允许将子类声明为泛型或具体。

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*'

【讨论】:

    猜你喜欢
    • 2022-01-24
    • 2020-12-24
    • 2021-01-13
    • 2017-08-14
    • 2022-01-17
    • 2016-04-06
    • 2018-08-12
    • 2020-12-09
    • 1970-01-01
    相关资源
    最近更新 更多