DEV Community

Israel Junior
Israel Junior

Posted on

BaseModel vs DataClass no Python

Em Python, tanto pydantic.BaseModel quanto dataclasses.dataclass são usados para definir estruturas de dados com atributos tipados, mas eles têm propósitos e características distintas. A seguir, explico as vantagens de usar pydantic.BaseModel em vez de dataclasses.dataclass na declaração da sua classe Request:

Vantagens de usar pydantic.BaseModel:

  1. Validação automática de dados:

    • O BaseModel do Pydantic realiza validação automática dos dados com base nos tipos definidos (por exemplo, str para text). Se você passar um valor inválido (como um inteiro para um campo str), o Pydantic lançará uma exceção (ValidationError) com detalhes claros.
    • Exemplo:
     from pydantic import BaseModel class Request(BaseModel): text: str # Válido  req = Request(text="Olá") print(req) # Request(text='Olá')  # Inválido  req = Request(text=123) # Levanta ValidationError 
  • Com dataclass, não há validação automática. Você pode atribuir qualquer tipo de dado a um atributo, mesmo que ele não corresponda à anotação de tipo, a menos que implemente validações manualmente.
  1. Conversão automática de tipos:

    • O Pydantic tenta converter automaticamente valores para o tipo esperado, quando possível. Por exemplo, se text espera uma str, mas você passa um número como "123", o Pydantic pode convertê-lo para string.
    • Exemplo:
     req = Request(text=123) # Converte 123 para "123" automaticamente 
  • Em dataclass, não há conversão automática; você precisa implementar isso manualmente.
  1. Suporte a tipos complexos e personalizados:

    • O Pydantic suporta tipos complexos como List, Dict, Optional, Union, e até mesmo outros modelos aninhados, com validação automática para todos os níveis.
    • Exemplo:
     from pydantic import BaseModel from typing import List class Item(BaseModel): name: str class Request(BaseModel): text: str items: List[Item] req = Request(text="teste", items=[{"name": "item1"}, {"name": "item2"}]) 
  • Com dataclass, você teria que implementar validações manuais para garantir que os dados aninhados sejam corretos.
  1. Serialização e desserialização:

    • O Pydantic facilita a conversão de objetos para formatos como JSON e dicionários (usando model_dump() ou model_dump_json()) e também a desserialização de JSON/dicionários para objetos.
    • Exemplo:
     req = Request(text="teste") print(req.model_dump()) # {'text': 'teste'}  print(req.model_dump_json()) # '{"text":"teste"}' 
  • Com dataclass, você precisa usar bibliotecas adicionais (como dataclasses.asdict) ou implementar métodos manuais para serialização/desserialização.
  1. Integração com APIs e frameworks web:

    • O Pydantic é amplamente usado em frameworks como FastAPI porque ele se integra perfeitamente com validação de entrada/saída de APIs, parsing de JSON e geração automática de esquemas OpenAPI.
    • Exemplo com FastAPI:
     from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Request(BaseModel): text: str @app.post("/request") async def create_request(req: Request): return req 
  • Com dataclass, você precisaria de lógica adicional para validar e parsear os dados de entrada.
  1. Configuração flexível e personalização:

    • O Pydantic permite configurações avançadas, como validações personalizadas usando decoradores (@field_validator) ou configurações globais via ConfigDict.
    • Exemplo:
     from pydantic import BaseModel, field_validator class Request(BaseModel): text: str @field_validator("text") def text_must_not_be_empty(cls, v): if not v.strip(): raise ValueError("Text cannot be empty") return v 
  • Em dataclass, você precisa implementar validações manualmente, geralmente no método __post_init__, o que pode ser menos elegante.
  1. Suporte a esquemas JSON:

    • O Pydantic gera automaticamente esquemas JSON (JSON Schema) para seus modelos, o que é útil para documentação e validação de APIs.
    • Exemplo:
     print(Request.model_json_schema()) 
  • Com dataclass, você precisaria de bibliotecas adicionais ou implementações manuais para gerar esquemas JSON.
  1. Tratamento de dados opcionais e padrão:

    • O Pydantic lida bem com valores opcionais, valores padrão e campos obrigatórios, com validação automática.
    • Exemplo:
     from pydantic import BaseModel from typing import Optional class Request(BaseModel): text: str optional_field: Optional[str] = None 
  • Em dataclass, você pode definir valores padrão, mas não há validação automática para garantir conformidade com tipos opcionais.

Quando usar dataclass em vez de BaseModel?

  • Casos simples sem validação: Se você precisa apenas de uma estrutura de dados leve, sem validação ou serialização automática, dataclass é mais simples e tem menos sobrecarga.
  • Performance: dataclass é geralmente mais leve em termos de desempenho, pois não realiza validações automáticas.
  • Projetos sem dependências externas: dataclass é parte da biblioteca padrão do Python (a partir do Python 3.7), enquanto o Pydantic é uma dependência externa.

Conclusão

A principal vantagem de usar pydantic.BaseModel em vez de dataclasses.dataclass na sua classe Request é a validação automática, conversão de tipos, serialização/desserialização e integração com APIs. Se você está lidando com entrada de dados (como em APIs REST, parsing de JSON ou formulários), o Pydantic é uma escolha superior porque reduz a necessidade de código boilerplate para validação e parsing. No entanto, se você precisa apenas de uma estrutura de dados simples e não quer dependências externas, dataclass pode ser suficiente.

Top comments (0)