GN⁺: Python 3.8의 TypedDicts는 생각보다 꽤 좋음
(blog.changs.co.uk)-
TypedDict
는 PEP-589에서 소개되었으며, Python 3.8에 도입되었음. 주로 딕셔너리의 타입 주석을 생성하는 데 사용됨. -
dataclass
나pydantic
을 사용하여 '레코드' 타입 데이터를 표현하는 대신,TypedDict
는 딕셔너리의 유연성을 활용하여 필드가 누락될 수 있는 상황에서 유리함. - 예를 들어,
Movie
클래스를 정의하고movie
변수에Movie
타입의 사전을 할당하는 방식
class Movie(TypedDict):
title: str
movie: Movie = {"title": "Avatar"}
Non-totality
-
TypedDict
은 필드가 누락될 수 있음을 나타내는 개념인 non-totality를 지원. HTTP PATCH 엔드포인트 구현 시 유용 -
dataclass
는 필드 누락 개념이 없어 어색할 수 있음 -
TypedDict
에서는total=False
로 설정하여 유연하게 필드 누락을 처리 가능 -
PEP-655에서는
Required
와NotRequired
로 개별 필드 표시 가능
TypedDict
를 **kwargs
로 사용
-
PEP-692는
TypedDict
를 사용하여 가변 키워드 인수를 입력할 수 있게 함 -
TypedDict
를 사용하면 코드가 장황해 보일 수 있으나, 여러 함수 정의에서 재사용 시 유용 - Non-totality와 함께 사용하면 더욱 강점 발휘
-
pytest.fixture
를 커스텀하면서 일부 인수를 그대로 전달하는 시나리오 등
-
- Sentinel 값으로 유사한 동작 구현 가능하나 타입 어노테이션이 어색해질 수 있음
의존성 주입에 TypedDict
사용
-
PEP-692는
TypedDict
를 사용한 함수 호출 시 타입 검사 가능하게 함 - 많은 리소스가 일부 의존성을 공유하는 상황에서 유용
- 모든 리소스의 kwargs를 합친 것과 유사한
TypedDict
를 정의 - 리소스가 임의의 인수를 받도록 재작성한 후
TypedDict
로 의존성 주입 - 타입 시스템을 통해 의존성 주입 시 인수 오류나 누락 검사 가능
- 리소스 시그니처 변경은 이상적이지 않으나 의존성 주입 프레임워크보다는 작은 변화
- 정적 타입 검사를 지원하지 않는 프레임워크가 많음
향후 기능
-
PEP-728은 추가 항목의 타입을 정의하고, 추가 항목을 허용하지 않는 닫힌 사전 정의 가능하게 함
- 레코드 타입을 더 정확하게 정의하는 데 도움
-
PEP-705는 읽기 전용 항목 지정 가능하게 함 (발표 시점에 따라 이미 출시되었을 수 있음)
- 직관적으로 호환되어야 하는 다른
TypedDict
간에 잠재적 변이(삭제)로 인한 문제 발생 가능한 상황 대응
- 직관적으로 호환되어야 하는 다른
GN⁺의 정리
-
TypedDict
는 딕셔너리의 유연성을 활용하여 필드가 누락될 수 있는 상황에서 유리함. -
TypedDict
는dataclass
나pydantic
과 같은 다른 데이터 구조보다 더 유연한 옵션을 제공함.- 도메인에 따라 적합한 도구를 선택하되,
TypedDict
의 장점도 염두에 둘 것
- 도메인에 따라 적합한 도구를 선택하되,
데이터가 외부에서 json 형태로 오거나 파이썬 외부로 export하는 일이 잦은 경우에는 TypedDict를 사용하면 좋고, 그게 아니라면 구조화된 dataclass나 NamedTuple을 사용하는 것을 추천합니다.
Hacker News 의견
-
동적 타입을 선호하는 사람들이 점점 타입 시스템의 중요성을 깨닫고 있음
- 더 나은 타입 시스템이 더 나쁜 타입 시스템보다 우수함
-
dataclass(slots=True)
를TypedDict
대신 사용하는 이유- 속성 접근이 더 빨라 코드가 더 빠름
- 슬롯 클래스는 더 적은 RAM을 사용하고, L1 캐시 압박이 적어 코드가 더 빠름
- 속성 접근 시
["foobar"]
대신.foobar
를 사용해 손목에 부담이 덜함 - 속성 이름을 잘못 입력하면 런타임 오류 발생
-
타입을 강제하는 시스템이 없다면
TypedDict
는 아무런 역할을 하지 않음- 문자열로 주석된 속성에 실수를 저장해도 기본 Python은 이를 막거나 경고하지 않음
- 타입을 실제로 강제하려면
Pydantic
같은 도구를 사용해야 함
-
"thank you think"라는 제목은 지나치게 무례하게 들림
- "than i thought"가 더 읽기 좋음
-
구독 관련 문장에서 "None"의 의미가 불명확함
- 문법이 복잡해 이해하기 어려움
-
TypedDict에 대한 개인적인 경험
- 코드의 가독성을 높이기 위해
TypedDict
를 사용해 dicts를 주석 처리함 - 코드 경로를 추적하는 시간을 줄일 수 있었음
- 더 나은 코딩 실력이 필요하지만, dict를 많이 사용하는 앱에서는 좋은 해결책임
- 코드의 가독성을 높이기 위해
-
TypedDict
의 기능은 좋지만 선언 구문이 복잡함