Python์ Dataclass: ๊ฐ๋ ๊ณผ ํ์ฉ๋ฒ
Python์ dataclass
๋ ์ฝ๋์์ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐํํ๊ณ ๊ด๋ฆฌํ๋ ๋ฐ ๋งค์ฐ ์ ์ฉํ ๊ธฐ๋ฅ์
๋๋ค. Python 3.7๋ถํฐ ๋์
๋ dataclass
๋ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๋ฅผ ์ค์ด๊ณ , ๋ ๊ฐ๋
์ฑ ์๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค ์ ์๋๋ก ๋์์ค๋๋ค. ์ด ๊ธ์์๋ dataclass
์ ๊ธฐ๋ณธ ๊ฐ๋
, ํน์ง, ์ฌ์ฉ๋ฒ, ๋ค์ํ ์ต์
์ ํฌํจํ ์ฌํ ๋ด์ฉ๊น์ง ๋ค๋ฃจ๊ฒ ์ต๋๋ค.
1. Dataclass๋?
dataclass
๋ ๋จ์ํ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ํด๋์ค๋ฅผ ์ ์ํ ๋ ์ ์ฉํ Python์ ๋ด์ฅ ๋ฐ์ฝ๋ ์ดํฐ์
๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ํด๋์ค์ ์์ฑ์, __repr__
, __eq__
๋ฑ ์ฌ๋ฌ ๋ฉ์๋๋ฅผ ์๋์ผ๋ก ์์ฑํด ์ค์ผ๋ก์จ ๋ฐ๋ณต์ ์ธ ์ฝ๋๋ฅผ ์ค์ด๊ณ , ๊ฐ๋
์ฑ์ ๋์ฌ์ค๋๋ค.
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
์์ ๊ฐ์ Person
ํด๋์ค๋ฅผ ์ ์ํ๋ฉด, ์๋์ผ๋ก ์์ฑ์ __init__
๊ณผ ๊ฐ์ ๋ฉ์๋๋ค์ด ์ ์๋ฉ๋๋ค.
person = Person(name="Alice", age=30)
print(person) # ์ถ๋ ฅ: Person(name='Alice', age=30)
2. Dataclass์ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
ํ์ ํ๋ ์ ์ํ๊ธฐ
dataclass
๋ ํด๋์ค์ ํ๋๋ฅผ ์๋์ผ๋ก ์์ฑํ๋ฏ๋ก, ํ์
ํํธ๋ฅผ ์ฌ์ฉํ์ฌ ํ์ ํ๋๋ฅผ ์ ์ํ ์ ์์ต๋๋ค.
@dataclass
class Book:
title: str
author: str
year: int
book = Book(title="1984", author="George Orwell", year=1949)
print(book) # ์ถ๋ ฅ: Book(title='1984', author='George Orwell', year=1949)
๊ธฐ๋ณธ๊ฐ ์ค์ ํ๊ธฐ
ํ๋์ ๊ธฐ๋ณธ๊ฐ์ ์ง์ ํ ์ ์์ผ๋ฉฐ, ์ด๋ dataclass
์์ ์ ๊ณตํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํ๋ฉ๋๋ค.
@dataclass
class Car:
make: str
model: str
year: int = 2020 # ๊ธฐ๋ณธ๊ฐ
car = Car(make="Toyota", model="Camry")
print(car) # ์ถ๋ ฅ: Car(make='Toyota', model='Camry', year=2020)
๊ธฐ๋ณธ๊ฐ์ด ์๋ ํ๋ ์์ ์ฃผ์
๊ธฐ๋ณธ๊ฐ์ด ์๋ ํ๋๋ ๊ธฐ๋ณธ๊ฐ์ด ์๋ ํ๋๋ณด๋ค ์์ ์์นํด์ผ ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด TypeError
๊ฐ ๋ฐ์ํฉ๋๋ค.
@dataclass
class Employee:
name: str
position: str = "Engineer"
salary: int
# ์ค๋ฅ: non-default argument 'salary' follows default argument 'position'
3. Dataclass์ ์ฃผ์ ์ต์ ๋ค
dataclass
๋ @dataclass
๋ฐ์ฝ๋ ์ดํฐ์ ๋ค์ํ ์ต์
์ ์ ๋ฌํ ์ ์์ต๋๋ค. ๋ํ์ ์ธ ์ต์
์ผ๋ก๋ frozen
, order
, repr
๋ฑ์ด ์์ต๋๋ค.
3.1 frozen ์ต์
frozen=True
๋ฅผ ์ค์ ํ๋ฉด ๊ฐ์ฒด๊ฐ ๋ถ๋ณ(immutable) ์ํ๊ฐ ๋ฉ๋๋ค. ์ฆ, ์์ฑ ํ ํ๋ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๊ฒ ๋ฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ฐ์ดํฐ์ ๋ถ๋ณ์ฑ์ ๋ณด์ฅํ ์ ์์ต๋๋ค.
@dataclass(frozen=True)
class Point:
x: int
y: int
point = Point(1, 2)
# point.x = 3 # ์ค๋ฅ: Cannot assign to field 'x' (frozen ์ํ)
3.2 order ์ต์
order=True
์ต์
์ ์ฌ์ฉํ๋ฉด ๋น๊ต ๋ฉ์๋(<
, <=
, >
, >=
)๋ฅผ ์๋์ผ๋ก ์์ฑํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ฐ์ดํฐ์ ํฌ๊ธฐ ๋น๊ต๊ฐ ๊ฐ๋ฅํ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
@dataclass(order=True)
class Student:
name: str
grade: int
s1 = Student("Alice", 85)
s2 = Student("Bob", 90)
print(s1 < s2) # ์ถ๋ ฅ: True (85 < 90)
3.3 repr ์ต์
repr=False
๋ก ์ค์ ํ๋ฉด __repr__
๋ฉ์๋์์ ํด๋น ํ๋๊ฐ ์ ์ธ๋ฉ๋๋ค. ๋ฏผ๊ฐํ ์ ๋ณด๊ฐ ํฌํจ๋ ํ๋์ ๊ฒฝ์ฐ ์ด๋ฅผ ์ ์ธํ ๋ ์ ์ฉํฉ๋๋ค.
@dataclass(repr=False)
class Account:
username: str
password: str
account = Account("user1", "pass123")
print(account) # ์ถ๋ ฅ: Account() (ํ๋ ํ์ ์ ๋จ)
4. ํ๋์ ๋ค์ํ ์ค์ - field()
dataclass
์ ํ๋๋ field()
ํจ์๋ฅผ ์ฌ์ฉํด ๋ณด๋ค ์ธ๋ถ์ ์ผ๋ก ์ค์ ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๊ธฐ๋ณธ๊ฐ์ ์ค์ ํ๊ฑฐ๋, ํน์ ํ๋๋ฅผ ๋น๊ต์์ ์ ์ธํ๋ ๋ฑ์ ์์
์ ํ ์ ์์ต๋๋ค.
from dataclasses import dataclass, field
@dataclass
class Movie:
title: str
year: int
rating: float = field(default=5.0) # ๊ธฐ๋ณธ๊ฐ ์ค์
reviews: list = field(default_factory=list) # ๋ฆฌ์คํธ ๊ธฐ๋ณธ๊ฐ ์ค์
movie = Movie(title="Inception", year=2010)
print(movie) # ์ถ๋ ฅ: Movie(title='Inception', year=2010, rating=5.0, reviews=[])
๋น๊ต์์ ์ ์ธ - compare=False
field()
์ compare=False
๋ฅผ ์ง์ ํ๋ฉด ํน์ ํ๋๋ฅผ ๋น๊ต์์ ์ ์ธํ ์ ์์ต๋๋ค.
@dataclass
class Product:
name: str
price: float
category: str = field(compare=False)
p1 = Product(name="Laptop", price=1000, category="Electronics")
p2 = Product(name="Laptop", price=1000, category="Computers")
print(p1 == p2) # ์ถ๋ ฅ: True (category๋ ๋น๊ต์์ ์ ์ธ๋จ)
5. dataclass
์์์ ๋ฉ์๋ ์ถ๊ฐ
dataclass
๋ ๋ฉ์๋ ์ถ๊ฐ๋ฅผ ๋ฐฉํดํ์ง ์์ต๋๋ค. ํ์ํ ๊ฒฝ์ฐ ์ฌ์ฉ์ ์ ์ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ ์ ์์ผ๋ฉฐ, ๋ฐ์ดํฐ ์กฐ์ ๋ฐ ๋น์ฆ๋์ค ๋ก์ง์ ํฌํจํ ์ ์์ต๋๋ค.
@dataclass
class Rectangle:
width: float
height: float
def area(self) -> float:
return self.width * self.height
rect = Rectangle(10, 5)
print(rect.area()) # ์ถ๋ ฅ: 50.0
6. Dataclass์ ์์
dataclass
๋ ์์๋ ์ง์ํฉ๋๋ค. ๋ถ๋ชจ ํด๋์ค์ dataclass
ํ๋๋ฅผ ์์ ํด๋์ค๊ฐ ์์๋ฐ๊ณ , ์ถ๊ฐ์ ์ธ ํ๋๋ฅผ ์ ์ํ ์ ์์ต๋๋ค.
@dataclass
class Animal:
name: str
@dataclass
class Dog(Animal):
breed: str
dog = Dog(name="Buddy", breed="Golden Retriever")
print(dog) # ์ถ๋ ฅ: Dog(name='Buddy', breed='Golden Retriever')
7. dataclass
์ __post_init__
__post_init__
๋ฉ์๋๋ dataclass
๊ฐ์ฒด๊ฐ ์์ฑ๋ ํ ์ถ๊ฐ์ ์ธ ์ด๊ธฐํ๊ฐ ํ์ํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, ํน์ ์กฐ๊ฑด์ ๋ฐ๋ผ ๊ฐ์ ๋ณ๊ฒฝํ๊ฑฐ๋ ๊ฒ์ฆ์ ์ํํ ์ ์์ต๋๋ค.
@dataclass
class Person:
name: str
age: int
def __post_init__(self):
if self.age < 0:
raise ValueError("Age cannot be negative")
person = Person("Alice", -5) # ์ค๋ฅ ๋ฐ์: Age cannot be negative
8. Dataclass์ ์ฅ๋จ์
์ฅ์
- ์ฝ๋ ๊ฐ๊ฒฐ์ฑ: ๊ธฐ๋ณธ ์์ฑ์์ ๋ค์ํ ๋ฉ์๋๊ฐ ์๋์ผ๋ก ์์ฑ๋์ด ์ฝ๋๊ฐ ๊ฐ๊ฒฐํด์ง๋๋ค.
- ํ์ ํํธ ์ง์: ํ๋์ ํ์ ์ ์ง์ ํด ํ์ ์์ ์ฑ์ ๋์ผ ์ ์์ต๋๋ค.
- ์๋ ๋น๊ต ์ฐ์ฐ ์ง์:
order=True
์ต์ ์ ์ฌ์ฉํด ๋น๊ต ์ฐ์ฐ์๋ฅผ ๊ฐํธํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค. - ๋ถ๋ณ์ฑ ์ง์:
frozen=True
๋ก ์ค์ ํ์ฌ ๊ฐ์ฒด๋ฅผ ๋ถ๋ณ์ผ๋ก ๋ง๋ค์ด ์์ ์ฑ์ ๋์ผ ์ ์์ต๋๋ค.
๋จ์
- ๊ฐ๋ณ ๊ธฐ๋ณธ๊ฐ ๋ฌธ์ : ๋ฆฌ์คํธ๋ ๋์
๋๋ฆฌ ๊ฐ์ ๊ฐ๋ณ ๊ฐ์ฒด๋ฅผ ํ๋์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฌ์ฉํ ๋ ์ฃผ์ํด์ผ ํฉ๋๋ค.
default_factory
๋ก ํด๊ฒฐํ ์ ์์ง๋ง, ์ด๋ฅผ ๋ชจ๋ฅด๋ฉด ์์์น ๋ชปํ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. - ์์ ์ ์ฝ: ๋ค์ค ์์๊ณผ ๊ฐ์ ๋ณต์กํ ์์ ๊ตฌ์กฐ์์๋ ๋ค์ ์ ์ฝ์ด ์์ ์ ์์ต๋๋ค.
- ์ฑ๋ฅ: ์ผ๋ฐ ํด๋์ค๋ณด๋ค ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ค์ ๋ ๋ง์ด ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ํนํ ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฑ๋ฅ์ ๋ฏธ์ธํ ์ฐจ์ด๊ฐ ์์ ์ ์์ต๋๋ค.
๊ฒฐ๋ก
Python์ dataclass
๋ ๋ฐ์ดํฐ ์ค์ฌ์ ํด๋์ค ์์ฑ์ ์์ด ์ฝ๋์ ๊ฐ๋
์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ํฌ๊ฒ ํฅ์์์ผ์ฃผ๋ ์ ์ฉํ ๋๊ตฌ์
๋๋ค. ๋ถํ์ํ ์ฝ๋๋ฅผ ์ค์ด๊ณ ๋ฐ์ดํฐ ๊ฐ์ฒด๋ฅผ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ผ๋ฉฐ, field()
์ค์ , frozen
๋ถ๋ณ ๊ฐ์ฒด, order
์ ๋ ฌ ๋ฑ์ ๋ค์ํ ์ต์
์ ํตํด ๊ณ ๋์ ์ปค์คํฐ๋ง์ด์ง์ด ๊ฐ๋ฅํฉ๋๋ค.
'Develop' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์คํ๋ผ์ธ ํ๊ฒฝ์์ Git ์ฌ์ฉ ๋ฐฉ๋ฒ: SSH๋ก ์๊ฒฉ ์ ์ฅ์ ์ ๊ทผํ๊ธฐ (0) | 2024.11.05 |
---|---|
C#) Grbage Collector (0) | 2024.04.22 |
Object-Oriented Programming ) Overroading,Override , Extend ? (0) | 2020.04.09 |