实例属性的可区分联合

问题描述 投票:0回答:1

假设我有以下课程

class MyClass:
    def __init__(self, ...):
        self.attr1: Union[Attr11, Attr12]
        self.attr2: Literal["val1", "val2", "val3"]
        self.attr3: Attr3
        ...
        self.attrn: Attrn

我对以下类型提示感兴趣:

if self.attr2 == "val1":
    # self.attr1 should be Attr11 here
else:
    # self.attr1 should be Attr12 here

我该怎么做?

python python-typing
1个回答
0
投票

您可以通过即将推出的实验性

TypeForm
来实现这一目标。

注意:目前(2025 年 1 月)仅由

pyright
支持并启用了实验性功能,例如您需要在
pyproject.toml
文件中添加以下行。

[tool.pyright]
enableExperimentalFeatures = true

from typing import Union, Literal, TypeGuard, Any, TypeVar
from typing_extensions import TypeForm, TypeIs

T = TypeVar("T")

def _narrow_type(attr: Any, condition: bool, to_type: TypeForm[T]) -> TypeIs[T]:
    return condition


class MyClass:
    def __init__(self, *args):
        self.attr1: Union[int, str]
        self.attr2: Literal["val1", "val2", "val3"]

        if _narrow_type(self.attr1, self.attr2 == "varl", int):
            reveal_type(self.attr1)  # Type of "self.attr1" is "int"
        else:
            # Note: using TypeGuard instead of TypeIs will not narrow the type, i.e. it stays int | str
            reveal_type(self.attr1)  # Type of "self.attr1" is "str"
© www.soinside.com 2019 - 2024. All rights reserved.