본문 바로가기
프로그래밍 언어/Python

[Python] 클래스 구조

by 토마토베이컨수프 2021. 11. 16.

단일 책임 원칙(SRP)이라는 원칙 아래 작성된 클래스의 전체적인 구조와, 그 구조의 세부적인 요소들에 대해 알아보겠습니다.

 

클래스의 구조는 크게 다음과 같이 8가지로 분류 됩니다. 딱히 정해진 순서는 없지만, 이 구조의 순서대로 클래스를 만드는 것을 많이들 권장합니다.

  1. 클래스 변수
  2. __init__ 메소드
  3. 내장 파이썬 특수 메소드
  4. 클래스 메소드
  5. 정적 메소드
  6. 속성(Property)
  7. 인스턴스 메소드
  8. Private 메소드

 

클래스 변수

상수나 기본 인스턴스 변수로, 클래스의 최상위에 표시합니다.

class Employee(Person):
    POSITION = ("Superwiser", "Manager", "CEO", "Founder")
    ...

 

__init__ 메소드

클래스 생성자로, 클래스를 호출하는 방법과 클래스를 시작하기 전에 제공할 클래스의 주요 입력에 대한 정보를 제공합니다.

class Employee(Person):
    ...
    def __init__(self, name, id):
        self._name = name
        self._id = id

 

특수 파이썬 메소드

클래스의 기본 동작을 변경하거나 클래스의 추가 기능을 제공하는 메소드입니다. 매직 메소드라고도 하며, 이에 관해 자세한 설명을 적어놓은 포스트가 있으니, 아래 링크를 참고해 주시길 바랍니다.

https://tomatobaconsoup.tistory.com/3?category=1027085 

 

[Python] 매직 메소드를 통한 기능 구현

매직 매소드란? 클래스 안에 있는 특별한 메소드 이며 대표적인 예로 __init__, __str__ 메소드가 있습니다. a = 1 b = 2 print(a + b) # 3 그리고, 예를 들어 위 코드처럼 a 와 b 는 각각 1 과 2를 할당한 순간 a

tomatobaconsoup.tistory.com

 

클래스 메소드

__init__ 메소드를 사용해 생성자를 생성하지 않고 클래스를 사용할 수 있는 다른 방법을 알려주는 메소드입니다. 메소드 위에 @classmethod를 적어주고, self 대신 cls를 사용합니다. 아래 코드처럼 다양한 형태의 데이터로 객체를 생성할 수 있는 클래스 메소드를 작성할 수 있습니다.

class User:
    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name
    
    @classmethod
    def using_string(cls, names_str):
        first, last = map(str, names_str.split(""))
        user = cls(first, last)
        return user
        
    @classmethod
    def using_json(cls, names_json):
        ...
        return user
        
data = User.using_string("Kyungmin Lee")
data = User.using_json(json_data)

 

정적 메소드

정적 메소드는 self나 cls 등 클래스의 특정 데이터에 접근할 필요가 없어 단독으로 존재할 수 있지만 클래스와 관련이 있는 메소드를 지칭합니다. 클래스 외부에 독립 함수로 유지할 수도 있지만, 클래스 내부에 위치시켜 클래스와의 연관성을 드러내 유틸리티 함수로서의 기능을 좀 더 쉽게 나타낼 수 있습니다. 메소드 위에 @staticmethod를 적어줍니다.

class BookPriceCalculator:
    PER_PAGE_PRICE = 8
    
    def __init__(self, pages, author):
        self.pages = pages
        self.author = author
        
    ...
    @staticmethod
    def price_to_book_ratio(market_price_per_share, book_value_per_share):
        return market_price_per_share / book_value_per_share

 

속성

@property 데코레이터를 이용하여 getter, setter 메소드를 만들고, 이를 활용하여 setter 메소드에서 유효성 검사도 할 수 있습니다.

class Temperature:
    def __init__(self, temperature=0):
        self._temperature = temperature
        
    @property
    def fahrenheit(self):
        return self._temperature
        
    @fahrenheit.setter
    def fahrenheit(self, temp):
        if not isinstance(temp, int):
            raise("Wrong input type")
        self._temperature = self._temperature * 1.8 + 32
        
obj = Temperature(20)
obj.fahrenheit = "30"	# Error

 

인스턴스 메소드

일반적인 메소드입니다. 클래스의 동작을 추가합니다.

 

Private 메소드

파이썬에는 클래스에 대한 private속성 개념이 없지만, 언더바(_)를 통해 메소드를 private으로 간주하는 것으로 합의된 상태입니다.

만약 public 클래스를 상속하려고 할 때, 해당 public 클래스와의 변수를 제어할 수 없는 경우, 변수 충돌을 방지하기 위해 언더바 두 개(__)를 사용하는 것이 좋습니다.

class Person:
    def __init__(self, name):
        self.age = 20
        self.name = name
        
    def get_name(self):
        return name
        
class Child(Person):
    def __init__(self, name):
        super().__init__(name)
        self.__age = 10
        
ch = Child("YG")
print(ch.age)	# 20
print(ch._Child__age)	# 10

 

추상 클래스

별개로, 추상 클래스를 통해 특정 클래스에 상속된 클래스가 예상대로 구현할 수 있도록 도움을 줄 수도 있습니다. 추상클래스를 통해 다음과 같은 효과를 얻을 수 있습니다.

  • 추상화를 사용해 인터페이스 클래스를 만들 수 있다.
  • 추상 메소드를 구현하지 않으면 인터페이스 사용을 불가능하게 할 수 있다.
  • 추상 클래스 규칙을 준수하지 않으면 초기 오류가 발생한다.

abc라는 모듈을 통해 추상 클래스를 만들 수 있습니다.

from abc import ABCMeta, abstractmethod

class Fruit(metaclass=ABCMeta):
    
    @abstractmethod
    def originated(self):
        pass
        
class Apple(Fruit):

    def originated(self):
        return "Asia"

 


참고 자료

  • <클린 파이썬: 효과적인 파이썬 코딩 기법, 수닐 카필 지음>

'프로그래밍 언어 > Python' 카테고리의 다른 글

[Python] 비동기 프로그래밍  (0) 2021.12.07
[Python] 데코레이터  (0) 2021.11.21
[Python] 제너레이터  (0) 2021.11.11
[Python] 유용한 데이터 구조  (0) 2021.11.07
[Python] 파이썬 다운 코딩  (0) 2021.11.05