一种类型如何使用泛型或联合提示 __new__ 方法实现?

问题描述 投票:0回答:0

如何使用通用输入提示我的

__new__
实现?

所以我有一个可以存储

str
decimal.Decimal
实例的类,它是输入
str
decimal.Decimal
类的子类。

此代码适用于 mypy 和 python:

from __future__ import annotations
import typing
import typing_extensions
import decimal
import random

T = typing.TypeVar('T', str, decimal.Decimal)

class StrOrDecimal(typing.Generic[T]):
    @typing.overload
    def __new__(cls, arg: decimal.Decimal) -> StrOrDecimalTyped.Decimal.StrOrDecimal[decimal.Decimal]:
        ...
    @typing.overload
    def __new__(cls, arg: str) -> StrOrDecimalTyped.Str.StrOrDecimal[str]:
        ...
    # def __new__(cls, arg: typing.Union[str, decimal.Decimal]): does not work
    def __new__(cls, arg):  # works
        if isinstance(arg, decimal.Decimal):
            return super(cls, StrOrDecimalTyped.Decimal.StrOrDecimal).__new__(StrOrDecimalTyped.Decimal.StrOrDecimal, arg)
        if isinstance(arg, str):
            return super(cls, StrOrDecimalTyped.Str.StrOrDecimal).__new__(StrOrDecimalTyped.Str.StrOrDecimal, arg)
        raise ValueError('Invalid value')

_StrOrDecimal = StrOrDecimal
# needed for mypy
class StrOrDecimalTyped:
    class Str:
        class StrOrDecimal(_StrOrDecimal[T], str):
            pass
    class Decimal:
        class StrOrDecimal(_StrOrDecimal[T], decimal.Decimal):
            pass

a_val = 'a'
a = StrOrDecimal(a_val)
print(a)

b_val = decimal.Decimal('1.2')
b = StrOrDecimal(b_val)
print(b)

choices: typing.List[typing.Union[str, decimal.Decimal]] = [a_val, b_val]
c_val = random.choice(choices)
c = StrOrDecimal(c_val)

try:
    reveal_type(a)
    reveal_type(b)
    reveal_type(c)
except NameError:
    typing_extensions.reveal_type(a)
    typing_extensions.reveal_type(b)
    typing_extensions.reveal_type(c)

但是如果使用这些签名中的任何一个:

def __new__(cls, arg: typing.Union[str, decimal.Decimal]):
def __new__(cls, arg: T):

我得到这个错误:

generic.py:19: 错误:“StrOrDecimal”的“__new__”参数 1 具有不兼容的类型“Type[generic.StrOrDecimalTyped.Decimal.StrOrDecimal[Any]]”;预期“类型 [generic.StrOrDecimal[T]]”

我该如何解决?

python python-3.x operator-overloading mypy typing
© www.soinside.com 2019 - 2024. All rights reserved.