【问题标题】:How to enforce dataclass fields' types? [duplicate]如何强制执行数据类字段的类型? [复制]
【发布时间】:2020-03-18 09:48:13
【问题描述】:

在这段代码中:

import dataclasses

@dataclasses.dataclass
class MyClass:
    value: str

obj = MyClass(value=1)

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

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

【问题讨论】:

  • Python 没有输入,也不会输入。如果您想使用类型检查,请尝试运行mypy
  • @Giacomo 并不意味着您根本不能在运行时强制执行类型……
  • @deceze 意思是你要自己实现。 OP 专门要求使用“单线/开关”之类的东西来打开类型检查。这不会发生。
  • 为此我创建了一个小型 Python 库:github.com/tamuhey/dataclass_utils 这个库可以应用于包含另一个数据类(嵌套数据类)和嵌套容器类型(如 Tuple[List[Dict...)的数据类跨度>

标签: python python-3.x python-dataclasses


【解决方案1】:

您可以声明自定义__post_init__ 方法(请参阅python's 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)

结果:

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'>`

【讨论】:

  • 这只会检查当前班级的注释,而不是来自任何父母。最好改用dataclasses.fields
  • 注意这在从__future__导入annotations时不起作用,那么type字段就变成了内置类型的字符串
猜你喜欢
  • 1970-01-01
  • 2020-09-01
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
  • 2023-03-08
  • 2011-04-24
  • 2017-04-18
  • 2016-03-31
相关资源
最近更新 更多