개요
질문이 해결되었습니다. 그러나이 답변은 데이터 클래스에 대한 기본적인 이해를 돕기 위해 실용적인 예제를 추가합니다.
파이썬 데이터 클래스는 정확히 무엇이며 언제 사용하는 것이 가장 좋습니까?
- 코드 생성기 : 상용구 코드를 생성합니다. 일반 클래스에서 특수 메소드를 구현하거나 데이터 클래스가 자동으로 구현하도록 선택할 수 있습니다.
- 데이터 컨테이너 : 데이터 를 보유하는 구조 (예 : 튜플 및 딕트), 종종 점 등의 속성 액세스 (예 : 클래스
namedtuple
등)가있는 구조 .
"default [s]를 갖는 변경 가능한 명명 된 튜플"
후자의 문구가 의미하는 바는 다음과 같습니다.
- 변경 가능 : 기본적으로 데이터 클래스 속성을 재 할당 할 수 있습니다. 선택적으로 불변으로 만들 수 있습니다 (아래 예 참조).
- namedtuple :
namedtuple
일반 클래스 와 같이 점으로 구분 된 속성 액세스가 있습니다 .
- 기본값 : 속성에 기본값을 할당 할 수 있습니다.
일반적인 클래스와 비교하여 기본적으로 상용구 코드를 입력하면 비용이 절감됩니다.
풍모
이것은 데이터 클래스 기능에 대한 개요입니다 (TL; DR? 다음 섹션의 요약 표 참조).
당신이 얻는 것
다음은 기본적으로 데이터 클래스에서 얻는 기능입니다.
속성 + 표현 + 비교
import dataclasses
@dataclasses.dataclass
#@dataclasses.dataclass() # alternative
class Color:
r : int = 0
g : int = 0
b : int = 0
이러한 기본값은 다음 키워드를 자동으로 설정하여 제공됩니다 True
.
@dataclasses.dataclass(init=True, repr=True, eq=True)
당신이 켤 수있는 것
적절한 키워드가로 설정된 경우 추가 기능을 사용할 수 있습니다 True
.
주문
@dataclasses.dataclass(order=True)
class Color:
r : int = 0
g : int = 0
b : int = 0
순서화 방법은 강력한 평등 테스트와 < > <= >=
유사하게 구현됩니다 (과부하 연산자 functools.total_ordering
:).
해시 가능, 가변
@dataclasses.dataclass(unsafe_hash=True) # override base `__hash__`
class Color:
...
객체는 잠재적으로 변경 가능하지만 (바람직하지 않을 수도 있음) 해시가 구현됩니다.
해시 가능, 불변
@dataclasses.dataclass(frozen=True) # `eq=True` (default) to be immutable
class Color:
...
이제 해시가 구현되었으며 객체를 변경하거나 속성에 할당 할 수 없습니다.
전반적으로, unsafe_hash=True
또는 경우 객체는 해시 가능합니다 frozen=True
.
자세한 내용은 원래 해싱 논리 테이블 을 참조하십시오.
당신이 얻지 못한 것
다음 기능을 사용하려면 특수 메소드를 수동으로 구현해야합니다.
포장 풀기
@dataclasses.dataclass
class Color:
r : int = 0
g : int = 0
b : int = 0
def __iter__(self):
yield from dataclasses.astuple(self)
최적화
@dataclasses.dataclass
class SlottedColor:
__slots__ = ["r", "b", "g"]
r : int
g : int
b : int
이제 객체 크기가 줄어 듭니다.
>>> imp sys
>>> sys.getsizeof(Color)
1056
>>> sys.getsizeof(SlottedColor)
888
경우에 따라 __slots__
인스턴스 작성 및 속성 액세스 속도도 향상됩니다. 또한 슬롯은 기본 할당을 허용하지 않습니다. 그렇지 않으면 a ValueError
가 발생합니다.
이 블로그 게시물의 슬롯에 대해 자세히 알아보십시오 .
요약표
+----------------------+----------------------+----------------------------------------------------+-----------------------------------------+
| Feature | Keyword | Example | Implement in a Class |
+----------------------+----------------------+----------------------------------------------------+-----------------------------------------+
| Attributes | init | Color().r -> 0 | __init__ |
| Representation | repr | Color() -> Color(r=0, g=0, b=0) | __repr__ |
| Comparision* | eq | Color() == Color(0, 0, 0) -> True | __eq__ |
| | | | |
| Order | order | sorted([Color(0, 50, 0), Color()]) -> ... | __lt__, __le__, __gt__, __ge__ |
| Hashable | unsafe_hash/frozen | {Color(), {Color()}} -> {Color(r=0, g=0, b=0)} | __hash__ |
| Immutable | frozen + eq | Color().r = 10 -> TypeError | __setattr__, __delattr__ |
| | | | |
| Unpacking+ | - | r, g, b = Color() | __iter__ |
| Optimization+ | - | sys.getsizeof(SlottedColor) -> 888 | __slots__ |
+----------------------+----------------------+----------------------------------------------------+-----------------------------------------+
+ 이러한 메소드는 자동으로 생성되지 않으며 데이터 클래스에서 수동 구현이 필요합니다.
* __ne__
는 필요 하지 않으므로 구현되지 않습니다 .
추가 기능
초기화 후
@dataclasses.dataclass
class RGBA:
r : int = 0
g : int = 0
b : int = 0
a : float = 1.0
def __post_init__(self):
self.a : int = int(self.a * 255)
RGBA(127, 0, 255, 0.5)
# RGBA(r=127, g=0, b=255, a=127)
계승
@dataclasses.dataclass
class RGBA(Color):
a : int = 0
전환
재귀 적 으로 데이터 클래스를 튜플 또는 dict로 변환하십시오 .
>>> dataclasses.astuple(Color(128, 0, 255))
(128, 0, 255)
>>> dataclasses.asdict(Color(128, 0, 255))
{r: 128, g: 0, b: 255}
한계
참고 문헌
- R. Hettinger의 이야기 에 Dataclasses : 모든 코드 생성기를 종료하는 코드 생성기
- T. Hunner의 더 쉬운 클래스 에 대한 이야기 : 모든 크 루프트가없는 파이썬 클래스
- 해싱 세부 사항에 대한 파이썬 문서
- 실제 파이썬의 가이드 에 파이썬 3.7에서 데이터 클래스에 궁극적 인 가이드
- A. 쇼의 블로그 게시물 에 파이썬 3.7 데이터 클래스의 개요 투어
- E. 데이터 클래스 에 대한 Smith의 github 저장소
namedtuple
s는 변경할 수 없으며 속성의 기본값을 가질 수 없지만 데이터 클래스는 변경할 수 있으며 가질 수 있습니다.