🐍

typedDict, dataclass, pydantic

に公開

文法

  • 表記方法
  • 補完の見え方

TypedDict

class TypedDictUser(TypedDict):
    name: str
    age: int
    is_active: bool

typedDict_user = TypedDictUser(name='Alice', age=30, is_active=True)

参照

logging.info(typedDict_user['age'])
logging.info(typedDict_user['is_active'])

補完

  • ほかの雑音がないはGood

dataclass

@dataclass
class DataclassUser:
    name: str
    age: int
    is_active: bool


dataclass_user = DataclassUser(name='Alice', age=30, is_active=True)

参照

logging.info(dataclass_user.age)
logging.info(dataclass_user.is_active

補完

pydantic

class PydanticUser(BaseModel):
    name: str
    age: int
    is_active: bool


pydantic_user = PydanticUser(name='Alice', age=30, is_active=True)

参照

logging.info(pydantic_user.age)
logging.info(pydantic_user.is_active)

補完

比較

dot演算子

typedDict_user['is_active']の良いところ

method = 'age'
logging.info(typedDict_user[method])

ただし、これはdataclassでも可能

@dataclass
class DataclassUser:
    name: str
    age: int
    is_active: bool
    detail: dict[str, str]


dataclass_user = DataclassUser(
    name='Alice',
    age=30,
    is_active=True,
    detail={'location': 'Wonderland'},
)
logging.info(dataclass_user.detail['location'])

さらに、TypedDictはキーに数字を使えないが、dataclassは使える
typedDict

dataclass

@dataclass
class DataclassUser:
    name: str
    age: int
    is_active: bool
    detail: dict[str, str]


dataclass_user = DataclassUser(
    name='Alice',
    age=30,
    is_active=True,
    detail={'202501': 'Wonderland'},
)
yyyymm='202501'
logging.info(dataclass_user.detail[yyyymm])

validationしたいか

dataclass + pydantic

dataclassのままでもpydanticでデシリアライズも検証も可能
ただし、ちゃんと resolved = TypeAdapter(DataclassUser).validate_python(data) で検証が必要

Digit6 = Annotated[
    str,
    StringConstraints(pattern=r'^[0-9]{6}$', strict=True),
]


@dataclass
class DataclassUser:
    name: str
    age: int
    is_active: bool
    detail: dict[str, str]
    yyyymm: Digit6


# ここでは検証されない
dataclass_user = DataclassUser(
    name='Alice',
    age=30,
    is_active=True,
    detail={'202501': 'Wonderland'},
    yyyymm='2025012',
)
# 辞書に戻して検証する必要がある
resolved2 = TypeAdapter(DataclassUser).validate_python(
    asdict(dataclass_user),
)


data = {
    'name': 'Bob',
    'age': 25,
    'is_active': False,
    'detail': {'202502': 'Builderland'},
    'yyyymm': '202502',
}
# ここで検証される
resolved = TypeAdapter(DataclassUser).validate_python(data)
logging.info(resolved)
INFO - DataclassUser(name='Bob', age=25, is_active=False, detail={'202502': 'Builderland'}, yyyymm='202502')

pydantic

自動検証される

Digit6 = Annotated[
    str,
    StringConstraints(pattern=r'^[0-9]{6}$', strict=True),
]

class PydanticUser(BaseModel):
    name: str
    age: int
    is_active: bool
    yyyymm: Digit6

# ここで検証される
pydantic_user = PydanticUser(
    name='Alice',
    age=30,
    is_active=True,
    yyyymm='202501',
)

Discussion