17

如何检查一个类是否dataclass在 Python 中?

我发现我可以检查__dataclass_fields____dataclass_params__属性的存在,但我很想找到一种更优雅的方法来做到这一点。

我希望使用类似inspect.isclass函数的东西。例如,可能是类似的东西inspect.isdataclass

Python有类似的东西吗?

谢谢。

4

2 回答 2

27

文档

import dataclasses
dataclasses.is_dataclass(something)

正如@Arne 在内部提到的,它只是检查hasattr(something, '__dataclass_fields__'),但我建议不要依赖这个属性并直接使用is_dataclass.

为什么你不应该依赖__dataclass_fields__

  • 此属性不是公共 API:文档中的任何地方都没有提到它。
  • 这是一个实现细节,因此不能保证在其他 python 实现中工作。但除此之外cPython,似乎还没有任何东西支持 Python3.7(截至 2019 年 5 月)。至少 Jython、IronPython 和 PyPy 不支持它,所以很难判断它们是否会使用相同的属性

其他所有内容,包括检查数据类类型和数据类实例之间的差异,都在is_dataclass方法文档中:

# (from the docs)
def is_dataclass_instance(obj):
    return is_dataclass(obj) and not isinstance(obj, type)
于 2019-05-13T05:29:23.413 回答
2

扩展上面的答案,以下说明了 的用法is_dataclass()

请记住:传递给的参数is_dataclass()可以是数据类或数据类的实例,True从方法调用返回。

In [1]: from dataclasses import dataclass

In [2]: @dataclass
   ...: class Bio:
   ...:     name: str
   ...:     age: int
   ...:     height: float
   ...:

In [3]: from dataclasses import is_dataclass

In [4]: is_dataclass(Bio)
Out[4]: True

In [5]: b = Bio('John', 25, 6.5)

In [6]: is_dataclass(b)
Out[6]: True

要检查是否b是数据类的实例而不是数据类本身:

In [7]: is_dataclass(b) and not isinstance(b, type)
Out[7]: True

Bio是一个数据类,因此以下表达式的计算结果为False

In [8]: is_dataclass(Bio) and not isinstance(Bio, type)
Out[8]: False

让我们检查一下常规课程:

In [9]: class Car:
   ...:     def __init__(self, name, color):
   ...:         self.name = name
   ...:         self.color = color
   ...:

我们知道Car不是数据类:

In [10]: is_dataclass(Car)
Out[10]: False

In [11]: c = Car('Mustang', 'Blue')

的实例都不Car是数据类实例:

In [12]: is_dataclass(c)
Out[12]: False
于 2019-05-13T06:37:50.360 回答