字段类型取决于其他字段的类型

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

是否可以创建一个类似的类

from typing import Union, Literal

class Foo:
    bar: Union[str, int]
    qux: Literal["str", "int"]

这样,如果

qux
Literal["str"]
,那么
bar
就是
str
类型,如果
qux
Literal["int"]
,那么
bar
就是
int
类型?可以注释一下吗?

我知道

typing.overload
,但我认为这与这个例子无关

python python-typing mypy
1个回答
5
投票

Python 的

typing
系统通常不支持依赖类型。但是,可以模拟一些特定情况。

对于数量较少的依赖类型,可以一一列举。这需要使各个类型通用:

from typing import Union, Literal, Generic, TypeVar

Bar = TypeVar("Bar", str, int)
Qux = TypeVar("Qux", Literal["str"], Literal["int"])


class GenericFoo(Generic[Bar, Qux]):
    bar: Bar
    qux: Qux

    # not always needed – used to infer types from instantiation
    def __init__(self, bar: Bar, qux: Qux): pass

然后可以定义依赖关系

  • 作为案例中的
    Union
    Foo = Union[GenericFoo[str, Literal["str"]], GenericFoo[int, Literal["int"]]]
    
    f: Foo
    f = GenericFoo("one", "str")
    f = GenericFoo(2, "int")
    f = GenericFoo("three", "int")
    
  • 通过
    overload
    实例化:
    class GenericFoo(Generic[Bar, Qux]):
        bar: Bar
        qux: Qux
    
        @overload
        def __init__(self, bar: str, qux: Literal["str"]):
            pass
    
        @overload
        def __init__(self, bar: int, qux: Literal["int"]):
            pass
    
        def __init__(self, bar: Bar, qux: Qux):  # type: ignore
            pass
    
© www.soinside.com 2019 - 2024. All rights reserved.