Python에서 데이터 클래스가 어떻게 작동하는지 이해

우리는 Python의 모듈(tuple이나 사전dict 같은 간단한 데이터 구조를 자주 사용한다.우리 생활에서, 우리는 거의 매일 그것들을 사용하여 데이터를 저장한다.
예를 들어, 우리는 아래의 코드 예시로 자동차 대상을 표시할 수 있다
# Using Dictionary
car = {"name": "Model X", "brand": "Tesla", "price": 120_000}

# OR using Tuple
car = ("Model X", "Tesla", 120_000)
그러나 우리가 더욱 복잡한 데이터를 처리해야 할 때 이러한 기본적인 데이터 구조는 그다지 이상적이지 않게 변한다.여기에서, 우리는 카가 문자열이나 정수가 아닌 카의 사전이나 원조를 대표한다는 것을 기억해야 한다.
위의 예에서 만약에 우리가 세 개의 필드(name, brandprice만 있다면 Tuple을 사용하여 우리의 자동차 대상을 표시하면 된다.카의 대상에 더 많은 필드 (예: manufacturer, condition 등을 추가할 때, 우리는 속성의 순서를 기억해야 한다.
사전을 사용하는 경우 dot notation (즉 car.name) 를 사용하여 우리의 속성에 접근할 수 없습니다.이 밖에 심층 삽입 사전의 사용은 왕왕 매우 혼란스럽다.
여기서, 우리는 일반적인 사전이나 원조의 더 좋은 대체 방안을 토론할 것이다.

포함된 주제
  • 명명원조
  • 데이터 클래스, 명명 모듈
  • 의 더 좋은 대체품
  • 사용자 정의 데이터 클래스
  • 데이터 클래스 사용 시기
  • 우리 시작합시다!

    Tuple으로 이름 붙여서 구하기
    더 흔히 볼 수 있는 방법은 파이톤 내장 namedtuple 라이브러리의 명칭 모듈 (collections 을 사용하는 것이다.
    위의 자동차 예제에서 명명된 Tuple의 형태는 다음과 같습니다.
    from collections import namedtuple
    
    Car = namedtuple('Car', ['name', 'brand', 'price'])
    car = Car('Model X', 'Tesla', 120_000)
    
    많이 좋아졌어요.그렇다면 왜 명명 원조를 계속 사용하지 않습니까?
    응, 명명 원조는 확실히 그 자체의 제한 집합이 있어.자동차 속성에 기본값을 지정할 수 없는 것 외에 명명 원조는 본질적으로 변할 수 없다.
    다음은 PEPon why we shouldn’t just use Named Tuple의 설명이다.
    또한 사전, 모듈, 심지어 명칭 모듈을 사용해도 사용자 정의 클래스 방법을 사용할 수 없습니다. 이것은 왜 일반적인 Python Class 을 사용하지 않는지 문제를 발생시킵니다.

    파이썬 클래스
    Python에서는 모든 것이 하나의 대상이며, 대부분의 대상은 속성과 방법이 있다.보통, 우리는 파이톤에서 class 을 사용하여 자신의 사용자 정의 대상을 만들 것입니다. 이 대상들은 자신의 속성과 방법을 가지고 있습니다.
    앞의 예제를 사용하여 간단한 자동차 객체를 작성합니다.
    class Car:
        def __init__(self, name: str, brand: str, price: int) -> None:
            self.name = name
            self.brand = brand
            self.price = price
    
    
    car1 = Car('Model X', 'Tesla', 120_000)
    car2 = Car('Model X', 'Tesla', 120_000)
    
    car1 == car2 # False. We need to write our own __eq__ method to handle this.
    
    자동차 대상에 새로운 속성을 추가할 때마다 우리는 그것들을 __init__ 방법에 전달해야 한다.만약 우리가 __repr__ 방법에 자동차 대상의 더욱 묘사적인 표시를 추가해야 한다면 어떻게 해야 합니까?만약 우리가 같은 자동차 대상의 두 개의 자동차 실례를 비교해야 한다면?
    솔직히 말해서, 우리가 자동차 물체 하나만 처리할 때, 일은 결코 그렇게 나쁘지 않았다.그러나 만약에 우리가 더 많은 종류, 예를 들어Manufacturer,CarDealer 등을 추가해야 한다면 어떻게 해야 합니까?
    네가 이미 알고 있는 바와 같이 코드가 중복되는 흔적은 어디에도 없고, 냄새도 매우 고약하다.솔직히 말해서, 우리가 정말로 맞춤형 방법을 필요로 하지 않으면, 우리는 명명 원조를 사용하는 것이 가장 좋다.
    나쁜 소식의 전달자로서 현실 생활에서는 왕왕 그렇지 않다.

    입력 데이터 클래스
    Python3.7에 도입된 Data Classesdataclasses)는 우리에게 분류 대상을 간소화하는 방법을 제공했다.간소화하기 위해서 데이터 클래스는 대량의 샘플 코드를 추상화하는 일반적인 클래스일 뿐입니다.
    Data Class로 이전 예제를 다시 작성하려면 기본 클래스를 @dataclass로 꾸밀 수 있습니다.
    from dataclasses import dataclass
    
    @dataclass
    class Car:
        name: str # Supports typing out of the box!
        brand: str
        price: int
    
    car1 = Car('Model X', 'Tesla', 120_000)
    car2 = Car('Model X', 'Tesla', 120_000)
    
    car1 == car2 # True. __eq__ is generated automatically.
    
    car2.name # Supports dot annotation!
    
    데이터 클래스의 가장 좋은 부분은 클래스의 공공 코드Dunder methods, 예를 들어 __repr____eq__를 자동으로 생성하여 모든 중복된 코드를 없애는 것이다.

    사용자 정의 데이터 클래스

  • 경우에 따라 데이터 클래스 필드를 사용자 정의해야 할 수도 있습니다.
    from dataclasses import dataclass, field
    
    @dataclass
    class Car:
       name: str = field(compare=False)  # To exclude this field from comparison
       brand: str = field(repr=False)  # To hide fields in __repr__
       price: int = 120_000
       condition: str = field(default='New')
    

  • 새로 만든 데이터 클래스 __init__ 에서 발생한 일을 덮어쓰기 위해서 __post_init__ 방법을 설명할 수 있습니다.예를 들어 우리는 자동차의 초기 조건에 따라 가격을 쉽게 덮어쓸 수 있다.
    from dataclasses import dataclass, field
    
    @dataclass
    class Car:
       name: str = field(compare=False)
       brand: str = field(repr=False)
       price: int = 120_000
       condition: str = field(default='New')
    
       def __post_init__(self):
          if self.condition == "Old":
                self.price -= 30_000
    
    old_car = Car('Model X', 'Tesla', 130_000, 'Old')
    # Car(name='Model X', price=100000, condition='Old')
    
  • 우리의 데이터 종류를 바꾸지 않기 위해 우리는 @dataclass(frozen=True)를 장식기로 추가하기만 하면 된다.

  • 데이터 클래스의 또 다른 좋은 용례는 우리가 끼워 넣은 사전을 처리해야 할 때이다.다음은 데이터 클래스가 무엇을 할 수 있는지 보여주는 간단한 예입니다.
    # ...
    from typing import List
    
    @dataclass
    class CarDealer:
       cars: List[Car]
    
    car3 = Car('Model S', 'Tesla', 89_000)
    car4 = Car('Model Y', 'Tesla', 54_000)
    car_dealer = CarDealer(cars=[car3, car4])
    
    # CarDealer(cars=[Car(name='Model S', price=89000, condition='New'), Car(name='Model Y', price=54000, condition='New')])
    
  • 마지막으로 뚜렷하지 않으면 데이터 클래스도 계승을 지원한다. 왜냐하면 그들의 행위는 확실히 우리의 이전 일반 클래스와 유사하기 때문이다.

  • 그럼 데이터 클래스는 언제 사용합니까?

    명명 모듈
    데이터 클래스의 사용은 일반적으로 명명 모듈의 사용과 비교된다.대부분의 경우 데이터 클래스는 명명 모듈과 같은 장점을 제공한다.
    unpack 변수가 필요한 경우 명명 모듈을 사용할 수 있습니다.

    자전
    우리의 사전에는 고정된 키가 있고, 그것들에 대응하는 값이 고정된 유형이 있을 때, 데이터 클래스를 사용하는 것이 거의 항상 좋다.
    간단히 말해서, 경험의 법칙은 상당히 간단합니다. 만약 당신이 만든 사전이나 클래스가 주로 밑바닥 데이터의 속성으로 구성된다면 데이터 클래스를 사용하십시오.이것은 너를 도와 많은 시간을 절약할 것이다.
    마지막으로 데이터 클래스는 모든 속성의 유형 정보를 보존하는데 이것은 커다란 부가 장점이다!

    결어
    마찬가지로 파이톤에서 일반 클래스를 만드는 것은 틀림없습니다.그러나, 이것은 우리의 클래스 실례를 설정하기 위해 대량의 중복된 템플릿 코드를 작성해야 한다는 것을 의미할 수도 있다.
    Data Class 는
  • 시간 절약 및 코드 중복 감소
  • 유연성이 향상되어 변경 가능 또는 변경되지 않음
  • 상속 지원
  • 사용자 지정 및 기본값 허용
  • 오해하지 마.파이톤의 모든 클래스가 데이터 클래스가 필요한 것은 아닙니다.데이터 클래스는 만능이 아니다.
    대부분의 경우, 우리는 필요하지 않으면 일을 복잡하게 해서는 안 된다는 것을 시종 기억해야 한다.우리가 지나치게 복잡한 일을 처리하지 않는다면, 좋은 낡은 사전 한 권으로 이 일을 완성할 수 있다.
    읽어주셔서 감사합니다!
    본문은 최초로 발표되었다jerrynsh.com

    좋은 웹페이지 즐겨찾기