簡體   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