如何将数据类中的字段类型注释为与其 __init__ 的类型不同?

How to annotate the type of field in dataclass to be different from the type of its __init__?

我创建了一个数据类 Foo,它接受任何可以转换为 int:

的类型
import dataclasses


@dataclasses.dataclass
class Foo:
    a: int

    def __post_init__(self):
        # Here `self.a` is converted to int, so this class accepts any type that can be converted to int
        self.a = int(self.a)


# mypy error: Argument 1 to "Foo" has incompatible type "str"; expected "int",
foo = Foo("1")
print(foo)
print(foo.a + 2)

输出:

Foo(a=1)
3

然而,mypy报错如下:

error: Argument 1 to "Foo" has incompatible type "str"; expected "int"

如果我将Foo.a的类型修改为Union[str, int],mypy报另一个错误:

error: Unsupported operand types for + ("str" and "int")

如何编写字段类型与初始化参数不同的数据类?

您想将 a 字段与 __init__ 采用的 a 参数分离。这基本上需要

a: InitVar[Union[SupportsInt, str]]

还有一个

a: int = field(init=False)

一个描述 __init__ 参数,一个描述字段。但是,你不能那样做。 InitVar 和字段不能同名。

你最好的选择是不使用数据类,但如果你绝对决定那样做,你就必须自己写 __init__:

@dataclasses.dataclass
class Foo:
    a: int
    
    def __init__(self, a: typing.Union[typing.SupportsInt, str]):
        self.a = int(a)