Проверьте, является ли класс классом данных в Python - PullRequest
1 голос
/ 13 мая 2019

Как я могу проверить, является ли класс dataclass в Python?

Я узнал, что могу проверить наличие атрибутов __dataclass_fields__ и __dataclass_params__, но я бы хотел найти более элегантный способ сделать это.

Я бы ожидал использовать что-то вроде inspect.isclass функции. Может быть, что-то вроде inspect.isdataclass, например.

Есть ли у Python что-то подобное?

Спасибо.

Ответы [ 2 ]

5 голосов
/ 13 мая 2019

Документы

import dataclasses
dataclasses.is_dataclass(something)

Как уже упоминалось @Arne, он просто проверяет hasattr(something, '__dataclass_fields__'), но я бы рекомендовал не полагаться на него:

  • это не публичный API: он не упоминается нигде в документации.
  • Это детали реализации, и поэтому не гарантируется работа в других реализациях Python.Но, кроме cPython, похоже, что Python3.7 еще ничего не поддерживает.По крайней мере, Jython, IronPython и PyPy не поддерживают его.

Все остальное, включая различия между проверкой типа класса данных и экземпляра класса данных, содержится в документах is_dataclass method

1 голос
/ 13 мая 2019

В продолжение ответа выше, следующее иллюстрирует использование 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
...