[英]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)
如果解决方案可以确保typ
是bar
类型的转换器,则加分!
好吧,这里有一些可行的方法,但也许没有演员表有更好的方法:
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.