【问题标题】:Typing the instance of a class in python [duplicate]在python中键入类的实例[重复]
【发布时间】:2020-10-14 21:05:55
【问题描述】:

Type[SomeType] 是否有反函数,所以Instance[Type[SomeType]] == SomeType

给了我一个类,我想注释调用它的构造函数的返回值

class FixedSizeUInt(int):
    size: int = 0
    def __new__(cls, value: int):
        cls_max: int = cls.max_value()
        if not 0 <= value <= cls_max:
            raise ValueError(f"{value} is outside range " +
                             f"[0, {cls_max}]")
        new: Callable[[cls, int], Instance[cls]] = super().__new__  ### HERE
        return new(cls, value)

    @classmethod
    def max_value(cls) -> int:
        return 2**(cls.size) - 1

编辑: 这个类是抽象的,它需要被子类化才能有意义,因为大小为 0 只允许 0 作为它的值。

class NodeID(FixedSizeUInt):
    size: int = 40

class NetworkID(FixedSizeUInt):
    size: int = 64

编辑 2:对于这种特定情况,使用泛型就足够了,如 https://stackoverflow.com/a/39205612/5538719 中所述。尽管如此,Type 的逆问题仍然存在。那么问题可能是:泛型是否会涵盖所有情况,从而永远不需要逆函数?

【问题讨论】:

  • 你能澄清一下你想在这里注释什么吗? __new__ 的返回值就是 FixedSizeUInt。是否要参数化cls 的类型,使其适用于所有子类?
  • @MisterMiyagi 是的,没错。我需要它是通用的,因此它适用于子类,因为您可以看到 size 变量设置为零,因此如果不进行子类化并将其更改为零以外的值,则使用此类是没有意义的
  • 你能解释一下你所说的编辑是什么意思吗?如果您的问题与其他问题有足够的不同,您的问题将被重新打开。 T 字面意思是“T 类型的实例”,所以给定 cls: Type[T] 一个 T 也是“一个 Instance[Type[T]]”(如果这样的东西被定义)。
  • 这足以涵盖所有不需要Instance[Type[T]] 的情况吗?

标签: python python-3.x type-hinting python-typing


【解决方案1】:

我相信你想要:

new: Callable[[Type[FixedSizeUInt], int], FixedSizeUInt] = ...

或者更动态一点:

from typing import TypeVar, Callable

T = TypeVar('T')

...

def __new__(cls: Type[T], value: int):
    ...
    new: Callable[[Type[T], int], T] = ...

不过,Type 的逆问题仍然存在。那么问题可能是:泛型是否会涵盖所有情况,从而永远不需要逆函数?

这不是泛型,而是一般的类型提示。以int 为例。 intint() 创建类的一个实例。在类型提示中,int 表示 int的实例。使用类作为类型提示总是谈论该类型的实例,而不是类本身。因为讨论instances-of是比较典型的情况,所以讨论类本身就不那么常见了。

因此,您需要在类型提示中使用一个类,而类型提示中的一个类表示该类的 instance of。从逻辑上讲,不需要Instance[int] 类型提示,因为您不能从非实例类型提示开始。相反,对于您要谈论的类的特殊情况,需要一个特殊的类型提示Type[int]

【讨论】:

  • 第一个选项是否适用于子类?
  • 不,这就是为什么你要改用TypeVar
  • 澄清一下,我同意Instance[int] 没有意义,我说的是Instance[cls] 其中cls: Type[int] 这样您就不需要为简单的情况设置类型变量,例如示例中介绍的那个。
  • cls 一开始就不是 static 类型提示,静态类型检查器无法对其进行评估。只有在运行时cls 才会收到一个值(恰好是一个类),然后才能对其进行评估。这就是为什么你需要cls: &lt;something&gt;,以便能够谈论“无论type cls 有什么”。
猜你喜欢
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 2017-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
  • 2015-08-07
相关资源
最近更新 更多