如果 init 重载,如何键入提示基于一个函数的 init 的返回类型

Jab*_*Jab 4 python type-hinting python-3.x

我有一个类在它的 init 中接受整数或浮点数,但所有的都必须是整数或浮点数,所以我正在使用它typing.overload来实现这一点,并且我希望能够根据给定的值键入提示函数的返回。

class Vector3:
    @overload
    def __init__(self, x: int, y: int, z: int) -> None:
        ...
    @overload
    def __init__(self, x: float, y: float, z: float) -> None:
        ...

    def __init__(self, x, y, z) -> None:
        self._x = x
        self._y = y
        self._z = z

    # This function
    def __key(self) -> tuple[int | float, int | float, int | float]:
        return (self._x, self._y, self._z)
Run Code Online (Sandbox Code Playgroud)

另外,我如何输入提示 x、y 和 z 的值?我计划用来@property混淆 _x、_y、_z 值,但也不知道如何输入提示它们。

@property
def x(self) -> int | float:
    return self._x
Run Code Online (Sandbox Code Playgroud)

che*_*ner 5

__init__根本不要超载。Vector3使用受约束的类型变量来代替泛型。

from typing import Generic, TypeVar

T = TypeVar('T', int, float)

class Vector3(Generic[T]):
    def __init__(self, x: T, y: T, z: T) -> None:
        self._x: T = x
        self._y: T = y
        self._z: T = z

    def __key(self) -> tuple[T, T, T]:
        return (self._x, self._y, self._z)

    @property
    def x(self) -> T:
        return self._x

    # etc
Run Code Online (Sandbox Code Playgroud)

然后

reveal_type(Vector3(1, 2, 3))  # Vector3[int]
reveal_type(Vector3(1., 2., 3.)) # Vector3[float]
reveal_type(Vector3(1, 2, 3.)) # Vector3[float], via promotion of int values to floats
reveal_type(Vector3('1', '2', '3'))  # type error, T cannot be bound to str
Run Code Online (Sandbox Code Playgroud)

请注意,在此上下文中,它int被视为 的子类型float