Написание универсального метода для класса данных для проверки типов

#python #python-3.x

#python #python-3.x

Вопрос:

Если у меня есть следующий класс данных:

 @dataclasses.dataclass
class Something:
    first: str
    last: str
    age: int = 0
    ...
  

Какой был бы хороший универсальный способ проверки типов всех аргументов? В настоящее время у меня есть что-то вроде:

 def verify_types(dataclass_obj):
    for field_name, field_info in dataclass_obj.__dataclass_fields__.items():
        value = getattr(obj, field_name)
        expected_type = field_info.type
        actual_type   = type(value)
        print (f"Field: {field_name} | Value: {value} "
               f"Type: {actual_type} | ExpectedType: {expected_type}"
        )
        if expected_type != actual_type:
            print ('Type error')
  

Есть ли лучший способ сделать это, чем этот (может быть, что-то вроде mixin , которое я мог бы добавлять каждый раз, когда я инициализирую класс данных?).

Ответ №1:

Одним из вариантов является использование __post_init__ метода:

 class StrictTypes:
    def __post_init__(self):
        for field_name, field_info in self.__dataclass_fields__.items():
            value = getattr(self, field_name)
            if type(value) != field_info.type:
                raise SystemExit(f"Invalid type of '{type(value).__name__}' on field {field_name}")

@dataclasses.dataclass
class Something(StrictTypes):
    ...
  

Ответ №2:

Другой способ принудительно использовать подсказки типа во время выполнения — использовать готовое решение, которое уже существует — пакет pydantic. Он обертывает класс данных, и ваш примерный код с использованием pydantic будет:

 from pydantic import BaseModel
class Something(BaseModel):
    first: str
    last: str
    age: int = 0
    ...
  

Как говорят авторы:

pydantic применяет подсказки типа во время выполнения и предоставляет удобные для пользователя ошибки, когда данные недопустимы.