Несмотря на название, dataclasses.dataclass
не предоставляет интерфейс класса.Это просто позволяет вам объявить пользовательский класс удобным способом, который делает очевидным, что он будет использоваться в качестве контейнера данных.Таким образом, в теории, есть небольшая возможность написать что-то, что работает только для классов данных, потому что классы данных на самом деле являются просто обычными классами.
На практике есть несколько причин, по которым вы хотите объявить функции только для классов данныхво всяком случае, и я вижу два способа сделать это.
Способ правильный , с использованием статической проверки типов и написания протокола
from dataclasses import dataclass
from typing import Dict
from typing_extensions import Protocol
class IsDataclass(Protocol):
# as already noted in comments, checking for this attribute is currently
# the most reliable way to ascertain that something is a dataclass
__dataclass_fields__: Dict
def dataclass_only(x: IsDataclass):
... # do something that only makes sense with a dataclass
@dataclass
class A:
pass
dataclass_only(A()) # a static type check should show that this line is fine
Этот подход также упоминается в вашем вопросе, но он имеет три недостатка:
- Вам нужна сторонняя библиотека, такая как
mypy
длясделайте для вас статическую проверку типов - Вам также необходимо установить
typing_extensions
, поскольку Protocol
еще не является частью основного модуля typing
- Последнее, но не менее важное, использование протоколов для классов данных таким образом сейчас не работает
Что-то немного больше EAFP Вдохновленный, что на самом деле работает
from dataclasses import is_dataclass
def dataclass_only(x):
"""Do something that only makes sense with a dataclass.
Raises:
ValueError if something that is not a dataclass is passed.
... more documentation ...
"""
if not is_dataclass(x):
raise ValueError(f"'{x.__class__.__name__}' is not a dataclass!")
...
В этом приложениида, поведение все еще очень ясно для сопровождающего или пользователя этого кода благодаря документации.Но недостатком является то, что вы не получаете статический анализ вашего кода (включая подсказки типов вашей IDE) ни сейчас, ни когда-либо.