Traffine I/O

日本語

2023-03-10

Pydanticモデルの継承

Pydanticモデルの継承

継承は、既存のクラスを基に新しいクラスを作成することで、機能を再利用し拡張するためのオブジェクト指向プログラミングの基本的なコンセプトです。この記事では、Pydanticモデルを継承して、より効率的かつメンテナブルなコードを作成する方法について紹介します。

ベースモデルの作成

まず、継承されるモデルの基盤となるベースモデルを作成する必要があります。Pydanticでは、モデルはBaseModelクラスを使用して定義されます。以下に簡単な例のモデルを作成します。

python
from pydantic import BaseModel, EmailStr

class User(BaseModel):
    id: int
    name: str
    email: EmailStr

ベースモデルの拡張

ベースとなるUserモデルがあるので、これを継承する新しいモデルを作成できます。enrollment_datemajorなどの追加フィールドを持つStudentモデルを作成したい場合は、次のようにUserモデルを拡張できます。

python
from datetime import date
from typing import Optional

class Student(User):
    enrollment_date: date
    major: Optional[str] = None

継承されたモデルにバリデータを追加

バリデータは、Pydanticモデルのデータを検証および前処理する関数です。継承されたモデルに追加して、カスタムルールを強制したり、データを格納する前に変更したりすることができます。Studentモデルにバリデータを追加するには、@validatorデコレータを使用します。

python
from pydantic import validator

class Student(User):
    enrollment_date: date
    major: Optional[str] = None

    @validator("enrollment_date")
    def validate_enrollment_date(cls, enrollment_date):
        if enrollment_date > date.today():
            raise ValueError("Enrollment date must be in the past")
        return enrollment_date

フィールドとメソッドをオーバーライド

場合によっては、継承されたモデル内のフィールドやメソッドをオーバーライドして、その動作を変更したい場合があります。その場合は、派生クラスでフィールドやメソッドを再定義します。

python
class Staff(User):
    role: str
    email: str  # Overriding the EmailStr type in the User model

    def get_role(self):
        return f"Staff role: {self.role}"

この例では、emailフィールドを任意の文字列を受け入れるようにオーバーライドし、有効な電子メールアドレスとして検証する代わりに任意の文字列を受け入れるようにしました。また、Staffクラスに新しいメソッドget_roleを追加しました。

Pydantic継承の実用的な例

この章では、Pydantic継承の実際の例を掘り下げ、実世界のアプリケーションでのこの機能の強力さと柔軟性を示します。

ユーザー認証

複数のユーザータイプ(例:AdminCustomerContentCreator)を持つWebアプリケーションを考えてみます。各ユーザータイプには、独自の属性や機能がある場合があります。 Pydantic継承を活用して、基本的なUserモデルを作成し、各ユーザータイプで拡張します。

python
# Base User model
class User(BaseModel):
    id: int
    username: str
    password: str
    email: EmailStr

# Admin model
class Admin(User):
    access_level: int

    def grant_permission(self, target_user: User):
        # Implementation to grant permission to target_user

# Customer model
class Customer(User):
    shipping_address: str
    billing_address: str

    def place_order(self, order: Order):
        # Implementation to place an order

# ContentCreator model
class ContentCreator(User):
    bio: Optional[str] = None

    def create_content(self, content: Content):
        # Implementation to create content

製品カタログ

ECアプリケーションでは、ElectronicsClothingFurnitureなどの異なる種類の製品がある場合があります。各製品タイプには固有の属性があります。 Pydantic継承を使用して、これらの製品タイプをモデル化する例を以下に示します。

python
# Base Product model
class Product(BaseModel):
    id: int
    name: str
    price: float
    description: str

# Electronics model
class Electronics(Product):
    brand: str
    warranty_period: int

# Clothing model
class Clothing(Product):
    size: str
    material: str
    gender: str

# Furniture model
class Furniture(Product):
    dimensions: Tuple[float, float, float]
    weight: float
    material: str

ブログ投稿モデル

ブログプラットフォームでは、ArticleVideoImageGalleryなどの様々なタイプのコンテンツがあります。各コンテンツタイプには固有の属性や機能がある場合があります。これらのコンテンツタイプのモデルを作成するために、Pydantic継承を使用できます。

python
# Base Content model
class Content(BaseModel):
    id: int
    title: str
    author: User
    created_at: datetime

# Article model
class Article(Content):
    body: str
    tags: List[str]

# Video model
class Video(Content):
    video_url: HttpUrl
    duration: int

# ImageGallery model
class ImageGallery(Content):
    images: List[HttpUrl]
    thumbnail: HttpUrl

参考

https://docs.pydantic.dev/usage/models/

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!