微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何键入提示一个在 Python 中其联合类型变窄的变量?

如何解决如何键入提示一个在 Python 中其联合类型变窄的变量?

我有一些辅助函数可以传递一个类型转换器和一个值。根据稍后发生的检查,我决定调用哪个辅助函数

如何正确注释类型以缩小下面 foo 变量的类型,以便它可以通过 mypy 检查?

from typing import Type,Union


def do_something(
        typ: Type[Union[float,int]],bar: Union[float,int]
) -> Union[float,int]:
    return bar


foo: Type[Union[float,int,str]] = float

assert foo is float or foo is int

do_something(foo,4.4)

如果解决方案可以确保 typbar 类型的转换器,则加分!

解决方法

好吧,这里有一些有效的方法,但也许有更好的方法,无需演员表:

from typing import Type,Union,cast


def do_something(
        typ: Type[Union[float,int]],bar: Union[float,int]
) -> Union[float,int]:
    return bar


foo: Type[Union[float,int,str]] = float

assert foo is float or foo is int

do_something(cast(Type[float],foo),4.4)
,

您需要的工具是 TypeVar

本质上,TypeVar 让你说“我不太清楚这是什么类型(虽然我可能有一些想法),但它在这个函数中的整个使用过程中都是一样的。” (或在某些情况下在整个类中使用)

例如,这可确保您拥有联合的每个事物在对函数的任何给定调用中都获得相同的值。

from typing import Type,TypeVar

# Define a type variable
# and list the things it is allowed to represent
NumberType = TypeVar("NumberType",float) 

def do_something(
        typ: Type[NumberType],bar: NumberType
) -> NumberType:
    return bar

这可以合法地用 do_something(float,2.5) 调用,在这种情况下它会返回一个浮点数,或者它可以用 do_something(int,2) 调用,在这种情况下它会返回一个 int。也就是说,它确保所有的东西都匹配。

因为您将其称为类型转换器,所以我怀疑您实际上可能并不希望所有类型都匹配。如果您需要限制多个类型变量,您可以使用更像

from typing import Callable,TypeVar

# Define a type variable
# and list the things it is allowed to represent
NumberTypeIn = TypeVar("NumberTypeIn",float)
NumberTypeOut = TypeVar("NumberTypeOut",float) 

def do_something(
        converter: Callable[[NumberTypeIn],NumberTypeOut],bar: NumberTypeIn
) -> NumberTypeOut:
    return type_(bar)

至于缩小 Type[] 的联合的原始问题,正如您所注意到的,is 不起作用。相反,您可以使用 issubclass,如

assert not issubclass(foo,str)

assert issubclass(foo,int) or issubclass(foo,float) 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。