[英]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.