데코레이터 @dataclass는 간단한 데이터 저장 클래스를 만들 때 템플릿 코드를 줄이기 위해 Python 3.7에서 도입된 도구 중 하나입니다. Python은 타입 주석을 통해 자동으로 __init__, __repr__, __eq__ 및 기타 메서드를 생성합니다.
문제의 역사:
dataclass가 도입되기 전, 개발자들은 수동으로 템플릿 클래스를 작성하고, 생성자, 비교 메서드, repr을 구현했으며, 이후 종종 명명된 튜플이나 attrs와 같은 라이브러리로 넘어갔습니다. @dataclass의 도입은 이 과정의 표준화 및 단순화를 가져왔습니다.
문제:
템플릿 코드(boilerplate)와 생성자 및 비교 메서드의 중복은 종종 오류를 야기하고 대규모 애플리케이션의 유지 관리를 복잡하게 했습니다.
해결책:
타입 주석 및 특별한 데코레이터 @dataclass를 사용하면 클래스에서 필요한 모든 메서드를 자동으로 생성할 수 있습니다.
코드 예:
from dataclasses import dataclass @dataclass class Point: x: int y: int p1 = Point(10, 20) p2 = Point(10, 20) print(p1 == p2) # True, 자동 생성된 __eq__ print(p1) # Point(x=10, y=20), 자동 생성된 __repr__
주요 특징:
@dataclass는 상속 동작에 영향을 미칩니까(상속 시 특징 내용)?
네. dataclass 클래스를 상속할 때 주의할 점은: 기본 클래스의 필드가 자식 클래스의 필드보다 먼저 나옵니다. 생성자/인수 순서에 충돌이 발생하면 오류가 발생할 수 있습니다. 기본과 자식 클래스의 서로 다른 필드에 동일한 이름이 있으면 자식 클래스의 필드가 기본 클래스를 덮어씁니다.
dataclass에서 필드의 기본값으로 변경 가능한 값을 사용할 수 있습니까?
아니요, 리스트와 같은 객체를 기본값으로 직접 사용할 수 없습니다 — field(default_factory=list)를 사용해야 합니다. 그렇지 않으면 모든 클래스 인스턴스가 동일한 컬렉션을 공유합니다.
예:
from dataclasses import dataclass, field @dataclass class User: values: list = field(default_factory=list)
@dataclass가 모든 시나리오에 대해 빠릅니까? 대량의 데이터 저장에 최적합입니까?
아니요. dataclass는 메모리 최적화 용도로 가장 효율적이지 않습니다. 수백만 개의 객체를 저장하려면 __slots__, namedtuple 또는 특별한 구조를 사용하는 것이 좋습니다. dataclass는 추가 필드를 추가하므로 슬롯처럼 메모리를 절약하지 않습니다. Python 3.10 이상에서는 slots=True 매개변수를 전달하여 조합할 수 있으며, 수동으로 slots를 사용할 수 있습니다.
@dataclass class Cart: items: list = [] # 오류! c1 = Cart() c2 = Cart() c1.items.append("a") print(c2.items) # ['a'] — 모든 Cart가 동일한 리스트를 공유함
장점:
단점:
from dataclasses import dataclass, field @dataclass class Cart: items: list = field(default_factory=list) c1 = Cart() c2 = Cart() c1.items.append("a") print(c2.items) # []
장점:
단점:
field(default_factory=...)에 대한 지식이 필요합니다 (별도의 학습이 필요함).