프로젝트를 진행하던 중 타입을 선택하는 것에 있어서 고민이 생겼고, 자료를 찾아가며 나름의 기준이 필요했다.
고민의 시작: dataclass 폭탄
처음으로는 Dataclass를 사용하였는데 사용하며 좀 마구잡이로 쓴 경향이 있지 않나 싶다.
이 고민은 한 책[전문가를 위한 파이썬(2판]에서 말하기를 추가적인 메서드 동작없이 타입만을 체크하기 위해 Dataclass 로 선언한것이라면, 냄새를 유발할 수도 있다는 의견을 보고 시작되었다.
왜 정적 타입이 필요하지?
동적 타이핑을 베이스로 두고 타입추론을 하는 파이썬은 다른 언어에 비해 유연하고 빠른 개발을 할 수 있는 특징이 있다.
하지만 여기서 정적 타입검사는 왜 나왔을까?
이건 동적 타입 언어의 특징에서 찾아 볼 수 있다.
exam = "나는문자열"
type(exam)
<class 'str'>
exam = 123
type(exam)
<class 'int'>
위 코드에서 보듯 , 동적 타입 언어는 런타임 중에 변수의 타입이 변경될 수 있다.
이런 경우 코드 작성을 할 때, 그러니까 개발 중에 에러가 발견 되지않고 테스트/실행 중 일 때 발견이 됩니다.
이건 실제로 개발 하면서도 느낀 문제점인데 작은 MVP사이즈 수준의 코드일 때는 문제가 되지 않는다.
단, 코드가 쌓이고 쌓일 때마다 개발속도는 점점 느려지게 되어 파이썬의 강점이 희석되는 느낌을 받았다.
정적타이핑에 대한 파이썬 개발자들에 대한 갈증은 2020년 Jetbrains의 파이썬 유저가 생각하는 파이썬의 필요한 추가 기능에 대한 설문 조사에서 성능향상과 병렬처리를 제치고 당당히 1위를 차지했다
https://www.jetbrains.com/lp/python-developers-survey-2020/
Python Developers Survey 2020 Results
Official Python Developers Survey 2020 Results by Python Software Foundation and JetBrains: more than 28k responses from more than 150 countries.
www.jetbrains.com
21% | Static typing, strict type hinting | 정적 타이핑, 엄격한 타입 힌팅 |
20% | Performance improvements | 성능 향상 |
15% | Better concurrency & parallelism | 더 나은 동시성 및 병렬 처리 |
아무튼 그래서 파이썬에는 정적 타입 검사 도구, 타입힌트, Pydantic 들로 동적타입 언어의 불편한 단점을 보완하는 것들이 많다.
나는 기본적인 typing, dataclass로 타입힌트를 적고 정적타입검사도구를 사용했다.
또한 FastAPI로 프로젝트를 하며 Pydantic에서 제공하는 Basemodel까지 사용하며 3가지의 적절한 사용 기준을 세웠다.
( typing, dataclass, Pydantic에 대한 설명은 스킵 )
위에서 말했듯 나는 dataclass를 사용하며 무차별적인 dataclass 폭탄을 만들었다.
이후 메서드가 없는 데이터 클래스 사용은 냄새를 유발할 수 있다. 를 책에서 본 뒤 기본적인 typing과 구분을 지어 사용하다가, Pydantic까지 사용하며 조금 더 기준을 명확히 하기로 했다.
코드가 혼란스러워지기도 했지만 기준이 잡혀가는 과정에서 겪어야 할 고통으로 받아들이기로 했다.
세 가지 구조체의 차이점 비교
기준 | Pydantic.BaseModel | dataclasses.dataclass | typing.TypedDict |
유효성 검사 | 있음 (자동 validation) | 없음 | 없음 |
직렬화 (.dict()) | 있음 | 직접 구현 필요 | -- |
FastAPI 연동 | 완벽히 호환 | 제한적 사용 (Body/Depends에 명시 필요) | 제한적 사용 (Body/Depends에 명시 필요) |
성능 | 약간 느림 (validation 비용) | 빠름 | 빠름 |
대표 용도 | API용 스키마, 요청/응답 | 중간 가공용 객체 | 가볍게 타입만 지정하고 싶을 때 |
pydantic의 성능이 약간 느림 인 이유는 아무 일도 하지 않는 2가지 방식에 비해서지 느린 것이 아닙니다!
( v2에서는 Rust로 core 검증 로직이 작성되어 더 빨라졌다고 합니다! )
이 부분은 하이퍼 커넥트에서 작성된 아티클도 보시면 좋습니다.
나만의 기준
그래서 각 방식의 특징으로 어느 정도 기준을 스스로 세워봤는데, 아마 대부분 비슷할 거라 생각합니다.
FastAPI 기준
용도 | 사용 |
API Request/Response 검증 | Pydantic |
DB model (NoSQL) | Pydantic or Dataclass [Pydantic 강추] |
DB model (SQL) | ORM + 입출력용으로 Pydantic 사용 |
로직 간 전달 객체 ( 데이터에 대한 작업이 있는 경우 ) | Dataclass or Pydantic |
로직 간 전달 객체 ( 데이터에 대한 작업이 없는 경우 ) | TypeDict 와 같은 기본 typing |
딕셔너리 / 튜플을 전달할때 명시된 단순 타입 전달 | TypeDict,NamedTuple 과 같은 typing |
타입 구조체는 단순한 취향의 문제가 아니라, 용도에 맞는 도구를 선택하는 전략이라 생각합니다.
각각의 구조체를 적재적소에 맞게 사용하면 설계가 명확하고 유지보수가 편해지며 불필요한 성능 낭비를 막아 줄 수 있다 생각합니다.
Pydantic = https://pydantic.com.cn/ko/
Pydantic에 오신 것을 환영합니다 - Pydantic 문서
피단틱 . Pydantic은 Python에서 가장 널리 사용되는 데이터 검증 라이브러리입니다. 빠르고 확장 가능한 Pydantic은 린터/IDE/뇌와 잘 작동합니다. 순수하고 표준적인 Python 3.8+에서 데이터가 어떻게 저
pydantic.com.cn
'Python > core' 카테고리의 다른 글
__contains__ (0) | 2025.01.25 |
---|