단일 책임 원칙(SRP)이라는 원칙 아래 작성된 클래스의 전체적인 구조와, 그 구조의 세부적인 요소들에 대해 알아보겠습니다.
클래스의 구조는 크게 다음과 같이 8가지로 분류 됩니다. 딱히 정해진 순서는 없지만, 이 구조의 순서대로 클래스를 만드는 것을 많이들 권장합니다.
- 클래스 변수
- __init__ 메소드
- 내장 파이썬 특수 메소드
- 클래스 메소드
- 정적 메소드
- 속성(Property)
- 인스턴스 메소드
- 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
클래스 메소드
__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 |