python数据类_init__方法中的强制类型转换

python数据类_init__方法中的强制类型转换,python,python-dataclasses,Python,Python Dataclasses,我有以下非常简单的数据类: import dataclasses @dataclasses.dataclass class Test: value: int from dataclasses import dataclass from pydantic import validate_arguments @validate_arguments @dataclass class Test: value: int 我创建了类的一个实例,但使用了字符串而不是整数: >

我有以下非常简单的数据类:

import dataclasses

@dataclasses.dataclass
class Test:
    value: int
from dataclasses import dataclass
from pydantic import validate_arguments


@validate_arguments
@dataclass
class Test:
    value: int

我创建了类的一个实例,但使用了字符串而不是整数:

>>> test = Test('1')
>>> type(test.value)
<class 'str'>
测试=测试('1') >>>类型(测试值) 我真正想要的是强制转换到我在类定义中定义的数据类型:

>>> test = Test('1')
>>> type(test.value)
<class 'int'>
测试=测试('1') >>>类型(测试值)
我必须手动编写
\uuuu init\uuuu
方法吗?还是有一种简单的方法来实现这一点?

数据类属性的类型提示在强制或检查类型的意义上永远不会得到遵守。大多数情况下,静态类型检查器(如)都需要完成这项工作,Python不会在运行时完成这项工作,因为它从来不会这样做

如果要添加手动类型检查代码,请使用以下方法:

您可以使用获取一个指定字段和类型的对象元组,并在该元组上循环,以自动为每个字段执行此操作,而无需为每个字段单独编写

def __post_init__(self):
    for field in dataclasses.fields(self):
        value = getattr(self, field.name)
        if not isinstance(value, field.type):
            raise ValueError(f'Expected {field.name} to be {field.type}, '
                             f'got {repr(value)}')
            # or setattr(self, field.name, field.type(value))

您可以使用
\uuu post\u init\uuu
方法实现这一点:

import dataclasses

@dataclasses.dataclass
class Test:
    value : int

    def __post_init__(self):
        self.value = int(self.value)
此方法在
\uuuu init\uuuu
方法之后调用


是的,简单的答案是自己在自己的
\uuuu init\uuuu()中进行转换。我这样做是因为我想要我的对象
freezed=True


对于类型验证,Pydandic声称可以这样做,但我还没有尝试过:

使用

只需在数据类中使用
validate\u参数
decorator:

import dataclasses

@dataclasses.dataclass
class Test:
    value: int
from dataclasses import dataclass
from pydantic import validate_arguments


@validate_arguments
@dataclass
class Test:
    value: int

然后尝试演示,“str type”1将从
str
转换为
int

>>> test = Test('1')
>>> type(test.value)
<class 'int'>

谢谢这并不完全是我想要的(例外而不是转换),但由于你的建议,我能够找到一个解决方案。我可能会在例外而不是隐式转换方面出错,但我在那里的评论中给了你转换选项……哎呀,没有看到最后的评论!另一种选择是使用装饰器而不是
\uuuuu post\u init\uuuuuuuu
。它在2021年4月开始测试,但看起来很神奇!