繁体   English   中英

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

[英]How can I type hint a variable whose Union type gets narrowed in Python?

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

如何正确注释类型以缩小下面的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 让你说“我不太清楚这是什么类型(尽管我可能有一些想法),但在 function 中的整个使用过程中,它都是同一个类型。” (或者在某些情况下,它在一个类中的整个使用过程中)

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

from typing import Type, TypeVar

# Define a type variable
# and list the things it is allowed to represent
NumberType = TypeVar("NumberType", int, 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", int, float)
NumberTypeOut = TypeVar("NumberTypeOut", int, 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) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM