如何强制执行数据类字段的类型?

Jun*_*ius 5 python python-3.x python-dataclasses

在这段代码中:

import dataclasses

@dataclasses.dataclass
class MyClass:
    value: str

obj = MyClass(value=1)
Run Code Online (Sandbox Code Playgroud)

数据类MyClass使用不遵守value类型的值进行实例化。

是否有一种简单的方法(使用装饰器、dataclass装饰器或库中的参数)来强制字段的类型,以便我的示例中的最后一行引发 aValueError或类似的东西?以这种方式强制执行类型有什么主要缺点吗?

Mar*_*her 7

您可以声明一个自定义__post_init__方法(请参阅python 的 doc)并将所有检查放在那里以强制类型检查。可以在父类中声明此方法以减少更改量。

import dataclasses


@dataclasses.dataclass()
class Parent:
    def __post_init__(self):
        for (name, field_type) in self.__annotations__.items():
            if not isinstance(self.__dict__[name], field_type):
                current_type = type(self.__dict__[name])
                raise TypeError(f"The field `{name}` was assigned by `{current_type}` instead of `{field_type}`")

        print("Check is passed successfully")


@dataclasses.dataclass()
class MyClass(Parent):
    value: str


obj1 = MyClass(value="1")
obj2 = MyClass(value=1)
Run Code Online (Sandbox Code Playgroud)

结果:

Check is passed successfully
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 3, in __init__
  File "<stdin>", line 7, in __post_init__
TypeError: The field `value` was assigned by `<class 'int'>` instead of `<class 'str'>`
Run Code Online (Sandbox Code Playgroud)

  • 请注意,当从“__future__”导入“annotations”时,这不起作用,然后“type”字段变成内置类型的字符串 (4认同)
  • 这只检查当前类的注释,而不是来自任何父类的注释。最好使用“dataclasses.fields”代替 (2认同)
  • 很好,也很有帮助。我需要修改我的类型以避免参数化泛型,因为 `isinstance(["this"],list[str])` 无效。 (2认同)