본문 바로가기
프로그래밍 언어(Programming Languages)/파이썬(Python)

[Python] @dataclass로 서점 데이터베이스 만들기

by 데이터 벌집 2023. 10. 13.

이번 포스팅에서는 파이썬 데이터 클래스를 활용하여 간단한 책 클래스를 만들어 보겠습니다. 
 

데이터클래스 예제

 
데이터 클래스의 기본 개념에 대해 알아보고 싶은 분은 밑에 포스팅을 참고하세요!
 
2023.10.11 - [파이썬(Python)] - [Python] @dataclass로 파이썬 클래스 마스터하기

[Python] @dataclass로 파이썬 클래스 마스터하기

오늘의 주제는 Python 3.7에서 소개된 '데이터 클래스'에 대한 것입니다. 이 데이터 클래스는 사용자 정의 클래스를 효율적으로 만들어주는 기능이며, 여러분들이 코딩하는 데 도움이 될 것입니다.

datasciencebeehive.tistory.com


책 클래스 (Book Class)

1. 책 클래스 정의하기

먼저, from dataclasses import dataclass, field 코드 부분은 파이썬의 dataclasses 모듈에서 dataclass와 field를 불러오는 부분입니다. dataclass는 데코레이터로 사용되며, 클래스를 간결하게 정의할 수 있도록 도와줍니다. field는 데이터 클래스의 필드를 정의하고 설정합니다.
 

from dataclasses import dataclass, field
from typing import Dict, List
from datetime import datetime

@dataclass
class Book:
    """
    Book 데이터 클래스

    Attributes:
    title (str): 책 제목
    author (str): 저자 이름
    pages (int): 페이지 수
    publisher (str): 출판사 (기본값: '미상')
    genre (str): 장르 (기본값: '미상')
    publication_year (int): 출판 연도 (기본값: None)
    price(float): 책 가격
    """
    title: str
    author: str
    pages: int
    publisher: str = field(default='미상')
    genre: str = field(default='미상')
    publication_year: int = field(default=None)
    price: float = field(default = 0)

 
이 부분에서는 Book이라는 데이터 클래스를 정의합니다. title, author, pages는 필수 속성이며, publisher, genre, publication_year는 기본값이 제공되는 옵셔널 속성입니다.

 

2. Methods

    def __str__(self):
        """책 정보를 문자열로 반환"""
        return f"'{self.title}' by {self.author}, {self.pages} 페이지, 출판사: {self.publisher}"

    def age_of_book(self):
        """책의 나이를 반환"""
        if self.publication_year is not None:
            return 2023 - self.publication_year  # 현재 연도는 2023으로 가정
        else:
            return '출판 연도 정보 없음'

    def is_genre(self, genre):
        """주어진 장르가 책의 장르와 일치하는지 확인"""
        return self.genre.lower() == genre.lower()

    def summary(self):
        """책의 요약 정보를 반환"""
        return f"{self.title}는 {self.author}에 의해 작성되었으며, {self.pages} 페이지로 구성되어 있습니다. 이 책은 {self.genre} 장르에 속하며, {self.publisher}에서 출판되었습니다."
  • str 메서드는 책의 제목, 저자, 페이지 수 등의 정보를 읽기 편한 문자열 형태로 반환합니다, 이로 인해 사용자가 Book 클래스의 인스턴스를 print 문으로 출력할 때, 책의 기본 정보를 쉽게 확인할 수 있습니다
  • age_of_book 메서드는 책의 출판 연도를 바탕으로 그 책이 몇 년 전에 출판되었는지를 계산합니다. 만약 출판 연도 정보가 없다면, '출판 연도 정보 없음'이라는 문자열을 반환합니다.
  • is_genre 메서드는 사용자로부터 입력받은 장르와 책의 장르를 비교하여, 두 장르가 일치한다면 True를, 그렇지 않다면 False를 반환합니다. 이 메서드는 문자의 대소문자를 구분하지 않기 때문에, 사용자가 장르를 대소문자를 구분 없이 입력해도 적절히 작동합니다.
  • summary 메서드는 책의 제목, 저자, 페이지 수, 장르, 출판사 등의 정보를 포함한 요약 정보를 문자열 형태로 반환합니다. 이 문자열은 책의 주요 정보를 빠르게 파악하기 위해 사용됩니다.

서점 클래스(BookStore Class)

1. 클래스 생성하기

1. 책 클래스 정의하기 먼저 책에 대한 기본 정보를 담을 수 있는 Book 클래스를 생성합니다. @dataclass 데코레이터를 사용하여 간편하게 클래스를 정의합니다. 여기에는 title, author, pages, 그리고 publisher 등의 속성이 포함됩니다.

@dataclass
class Bookstore:
    """
    Bookstore 데이터 클래스.

    속성:
    name (str): 서점의 이름.
    books (Dict[str, Book]): ISBN을 키로 가지고 Book 객체를 값으로 가지는 사전.
    purchase_history (List[dict]): 구매 이력을 저장하는 리스트.
    
    """
    name: str
    books: Dict[str, Book] = field(default_factory=dict)
    purchase_history: List[dict] = field(default_factory=list)

 

2. Methods

책 재고 증가

    def add_book(self, book: Book):
        """
        새로운 책을 서점에 추가하거나 기존 책의 재고를 증가시킨다.

        매개변수:
        book (Book): 서점에 추가될 Book 객체.

        동일한 ISBN을 가진 책이 이미 서점에 있을 경우, 기존 책의 재고를 증가시킨다.
        그렇지 않으면, 새 책을 서점에 추가한다.
        """
        if book.isbn in self.books:
            self.books[book.isbn].stock += book.stock
        else:
            self.books[book.isbn] = book

책 판매

    def sell_book(self, isbn: str, quantity: int):
        """
        책을 판매하고, 거래를 구매 이력에 기록한다.

        매개변수:
        isbn (str): 판매될 책의 ISBN.
        quantity (int): 판매될 책의 수량.

        서점이 충분한 책의 재고를 가지고 있지 않다면 경고 메시지를 출력한다.
        그렇지 않으면, 재고를 줄이고 거래를 구매 이력에 기록한다.
        """
        if isbn not in self.books or self.books[isbn].stock < quantity:
            print(f"{isbn}의 ISBN을 가진 책이 충분하지 않습니다.")
        else:
            self.books[isbn].stock -= quantity
            self.purchase_history.append({
                'isbn': isbn,
                'quantity': quantity,
                'total_price': self.books[isbn].price * quantity,
                'timestamp': datetime.now()
            })
            print(f"{isbn}의 ISBN을 가진 책 {quantity}권 판매 완료.")

책 재고 출력

    def show_stock(self):
        """
        서점의 모든 책의 재고를 출력한다.

        서점의 모든 Book 객체를 순회하며, 각 책의 제목과 현재 재고를 출력한다.
        """
        for book in self.books.values():
            print(f"{book.title}: 재고 {book.stock}권")

서점의 구매 이력 출력

    def show_purchase_history(self):
        """
        서점의 구매 이력을 출력한다.

        구매 이력의 모든 거래를 순회하며, 이를 출력한다.
        """
        for purchase in self.purchase_history:
            print(purchase)

교보문고 서점 데이터베이스 예제

 
 

# 책 인스턴스 생성
harry_potter = Book(
    isbn="978-3-16-148410-0",
    title="Harry Potter and the Philosopher's Stone",
    author="J.K. Rowling",
    pages=223,
    publisher="Bloomsbury",
    genre="Fantasy",
    publication_year=1997,
    price=19.95,
    stock=20  # 재고 수량
)

da_vinci_code = Book(
    isbn="978-0-385-50420-9",
    title="The Da Vinci Code",
    author="Dan Brown",
    pages=689,
    publisher="Doubleday",
    genre="Thriller",
    publication_year=2003,
    price=24.95,
    stock=15  # 재고 수량
)

science_book = Book(
    isbn="978-0-12345-678-9",
    title="A Brief History of Time",
    author="Stephen Hawking",
    pages=256,
    publisher="Bantam Books",
    genre="Science",
    publication_year=1988,
    price=18.99,
    stock=30  # 재고 수량
)

# 서점 인스턴스 생성
kyobo = Bookstore(name="교보문고")

# 서점에 책 추가
kyobo.add_book(harry_potter)
kyobo.add_book(da_vinci_code)
kyobo.add_book(science_book)

# 재고 확인
kyobo.show_stock()
# Output:
# Harry Potter and the Philosopher's Stone: 재고 20권
# The Da Vinci Code: 재고 15권
# A Brief History of Time: 재고 30권

# 책 판매
kyobo.sell_book("978-0-385-50420-9", 5)  # 다빈치 코드 5권 판매
# Output:
# 978-0-385-50420-9의 ISBN을 가진 책 5권 판매 완료.

# 판매 후 재고 확인
kyobo.show_stock()
# Output:
# Harry Potter and the Philosopher's Stone: 재고 20권
# The Da Vinci Code: 재고 10권
# A Brief History of Time: 재고 30권

# 판매 이력 확인
kyobo.show_purchase_history()
# Output:
# {'isbn': '978-0-385-50420-9', 'quantity': 5, 'total_price': 124.75, 'timestamp': datetime.datetime(2023, 9, 19, 14, 41, 15, 975154)}

 


dataclasses 모듈을 활용하면 데이터를 표현하는 클래스를 간결하고 효과적으로 생성할 수 있습니다. 오늘의 예제를 통해 서점의 책 데이터를 관리하는 간단한 시스템을 만들어 보았는데요, dataclasses의 다양한 기능을 활용하면 여러분의 프로젝트에서 데이터 관리를 더욱 효율적으로 진행할 수 있습니다.