首页 > 解决方案 > 在python中键入类的实例

问题描述

有反函数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仍然存在。那么问题可能是:泛型是否会涵盖所有情况,从而永远不需要逆函数?

标签: pythonpython-3.xtype-hintingpython-typing

解决方案


我相信你想要:

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 表示 . 使用类作为类型提示总是谈论该类型的实例,而不是类本身。因为讲instances-of是比较典型的情况,讲类本身就比较少见了。int

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


推荐阅读