클래스 수준의 속성/메서드 VS 인스턴스 수준의 속성/메서드

 

클래스의 구성요소인 속성(attribute)과 메서드(method)는 클래스를 구현하고 실행하여 인스턴스를 생성하고 사용하는 과정에서 클래스 수준에서 사용되는 속성과 메서드, 그리고 인스턴스 수준에서 사용되는 속성과 메서드로 구분할 수 있다.

 

  인스턴스 수준 클래스 수준
속성 (Attribute) 각각의 인스턴스가 가진 고유값 여러 인스턴스가 같은 값을 공유
매서드 (Method) 인스턴스에서 호출할 수 있는 메서드
인스턴스 값을 핸들링
클래스 속성을 수정하거나 클래스 레벨에서 공통적으로 관리하는 동작을 수행할 때 사용

 

인스턴스 수준의 속성은 각각의 인스턴스가 자신의 고유값을 갖는다. 그리고 이 고유의 값을  즉 인스턴스 하나를 인식하고 그 값을 핸들링(초기화, 수정, 삭제 등) 하는 메서드를 인스턴스 메서드라 한다. 반면에 클래스 수준의 속성은 클래스의 모든 인스턴스가 한 값을 공유한다. 그리고 이 값을 핸들링 하는 매서드를 클래스 매서드라 한다. 

 

예를 들어 고양이 클래스에서 모든 고양이 인스턴스들을 고양이과에 속한다. 그래서 species(종) 속성은 '고양이과'라는 모든 인스턴스가 공유하는 값을 가진다. 그리고 이 값을 리턴하는 클래스 수준의 매서드 getSpecies()를 정의한다. 

 

위 구조를 파이썬 코드로 구현하면 아래와 같다. 

class Cat:
    __species = "고양이과"  # 클래스 변수
    def __init__(self, name, color, size, gender, breed):
        self.__name = name
        self.__color = color
        self.__size = size
        self.__gender = gender
        self.__breed = breed
    def get_name(self): return self.__name
    def get_color(self): return self.__color
    def get_size(self): return self.__size
    def get_gender(self): return self.__gender
    def get_breed(self): return self.__breed
    
    def meow(self):
        print(f"{self.__name}: 야옹!") 
    
    @classmethod
    def get_species(cls): return cls.__species
 
# 인스턴스 생성
cat1 = Cat("구글링_고양이1", "고등어/흰색", "중형", "암컷", "코숏")
cat2 = Cat("봄비", "카오스", "중형", "암컷", "코숏")
cat3 = Cat("쿠키", "치즈냥이", "중형", "수컷", "코숏")
 
# 정보 출력
for cat in [cat1, cat2, cat3]:
    print("이름:", cat.get_name())
    print("색상:", cat.get_color())
    print("크기:", cat.get_size())
    print("성별:", cat.get_gender())
    print("품종:", cat.get_breed())
    print("종:", cat.get_species())
    print("종:", Cat.get_species())
    
    cat.meow()
    print()

 

  • 클래스 수준의 속성 정의 : 위 코드에서는 2라인의 __species라는 속성이 클래스 수준의 속성으로 정의되었다.  즉, 생성된 Cat 클래스의 인스턴스는 모두 __species라는 속성을 가지고 그 값은 "고양이과" 이다. 
  • 클래스 수준의 속성 사용(getter 정의): 클래스 밖에서 클래스 수준의 속성인 __species를 사용하기 위해 get_species(cls) 메소드를 @classmethod 데코레이터를 사용하여 정의하였다. 클래스 수준의 메소드는 인스턴스 수준의 메소드와 달리 self 가 아닌 class의 약자인 cls를 파라메터로 받는다. 
  • 클래스 수준의 getter 사용: 클래스 밖에서 get_species( )인 클래스 수준의 메소드를 호출할 때는 생성한 Cat 타입의 인스턴스를 받는 cat변수의 cat.get_species()를 호출해도 되고, 클래스 명 자체를 붙여 Cat.get_species()를 호출해도 된다. 

또 다른 예로,  도서관 시스템의 예에서도 BookLoan 클래스에 아래와 같은 도서대출 1,2,3의 인스턴스를 생성할 수 있다. 도서 대출 클래스의 클래스 수준 속성은 아래와 같다.

  • max_loan_days: 도서대출 기간이 2주라고 한다면 모든 도서대출 인스턴스가 도서대출 신청한 날짜에 2주후로 due_date 값을 계산해야 한다. 즉, 모든 인스턴스가 max_loan_days의 값을 공유한다. 
  • book_loan_list: 고양이의 species와 max_loan_days와 다른 리스트 형태의 클래스 수준 속성이다. 이 리스트는 BookLoan클래스 타입으로 생성된 모든 인스턴스의 리스트이다. 즉, 클래스 외부에서 book_loan1 = BookLoan( ...) 으로 클래스 인스턴스를 생성하면, BookLoan 클래스의 생성자에서 생성된 인스턴스를 해당 리스트에 append()한다. 따라서 BookLoan 클래스 밖에서는 생성한 대출 클래스의 인스턴스 전체를 book_loan_list 에서 찾을 수 있다. 

 

이를 파이썬 코드로 구현하면 아래와 같다. 

class BookLoan:
    __max_loan_days = 14          # 클래스 변수
    __book_list = []              # 클래스 변수: 전체 대출 목록
 
    def __init__(self, loan_id, book, user, loan_date):
        self.__id = loan_id
        self.__book = book
        self.__user = user
        self.__loan_date = loan_date
        self.__due_date = f"{loan_date} + {BookLoan.__max_loan_days}일"
        self.__return_date = "0000-00-00"
        self.__status = "Borrowed"
 
        # 생성된 객체를 클래스 변수 BookList에 추가
        BookLoan.__book_list.append(self)
 
    def borrow_book(self):
        print(f"{self.__user}가 {self.__book}을(를) 대출했습니다.")
 
    def return_book(self, return_date):
        self.__return_date = return_date
        self.__status = "Returned"
        print(f"{self.__book} 반납 완료")
 
    def extend_loan(self, days):
        print(f"대출 기간 {days}일 연장")
 
    def check_status(self):
        print(f"[{self.__id}] {self.__book} / {self.__status}")
 
    @classmethod
    def get_max_loan_days(cls):
        return cls.__max_loan_days
 
    @classmethod
    def print_book_list(cls):
        print()
        print("========== 전체 대출 목록 ==========")
        for loan in BookLoan.__book_list:
            loan.check_status()
        print()
 
 
# 객체 생성
loan1 = BookLoan("BL20250305001", "BKH001", "ST240101", "2025-03-05")
loan2 = BookLoan("BL20250305002", "BKSC001", "ST191101", "2025-03-05")
loan3 = BookLoan("BL20250305003", "BKE001", "ST200101", "2025-03-05")
 
# 전체 대출 목록 출력
BookLoan.print_book_list();
 
print("최대 대출 기간:", BookLoan.get_max_loan_days(), "일")

 

  • 3라인 클래스 수준의 속성 생성:  클래스 수준의 속성으로 __book_list를 리스트 타입으로 정의하였다.
  • 15라인 리스트에 인스턴스 대입: 클래스 인스턴스 생성시, 즉 생성자 __init__()에서 self 인스턴스가 만들어지면 __book_list.append(self)로 __book_list에 해당 인스턴스를 append 한다. 
  • 35 ~ 41라인 __book_list의 인스턴스 목록을 출력
  • 50 라인 생성된 BookLoan의 __book_list 목록을 출력하는 클래스 수준의 메서드를 호출한다. 

+ Recent posts