Post

Python study 8 - 클래스

Python 클래스와 관련된 내용을 학습합니다.

Python에서 사용되는 개념의 일부 혹은 전체를 정리하여 반복학습에 사용합니다.

  • 특수한 메소드에 대해 학습합니다.
  • 캡슐화에 대해 학습합니다.
  • 상속에 대해 학습합니다.


특수한 메소드


  • 비교 연산자 구현
1
2
3
4
5
6
def __eq__(self, value): # self == value
def __ne__(self, value): # self != value
def __gt__(self, value): # self > value
def __ge__(self, value): # self >= value
def __lt__(self, value): # self < value
def __le__(self, value): # self <= value
  • 사칙 연산자 구현
1
2
3
4
5
def __add__(self, value):  # 더하기 +
def __sub__(self, value):  # 빼기 - 
def __mul__(self, value):  # 곱하기 * 
def __truediv__(self, value):  # 나누기 /
def __floordiv__(self, value):  # 정수 나누기 //
  • 문자열 출력
1
2
def __str__(self):
    return "문자열"
  • 값 객체

    특정 길이를 기본자료형으로 cm로 파악하여 숫자를 적다가 다른사람 혹은 나중에 inch로 착각하여 길이가 꼬이는 경우가 발생될 수 있습니다.
    그래서 프로그램의 규모가 커지게되면 기본자료형의 사용을 막아버리고 클래스로 구현하게 됩니다.
    값을 하나들고있는 객체를 값 객체라고하며, 이를통해 값을 안전하게 만들고 보호할 수 있습니다.
    참고로 NASA에서 단위실수로 막대한 금액의 손실이 일어난 적이 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
class CmLength:
    def __init__(self, cm):
        if cm < 0:
            raise "길이는 0 이상으로 지정해야 합니다."
        self.__length = cm
    def get(self):
        return self.__length
    def __add__(self, other):
        if type(other) != CmLength:
            raise "길이 단위를 통일해주세요!"
        return CmLength(self.get() + other.get())

CmLength(3) + CmLength(5)


캡슐화


캡슐화는 객체를 사용할 때 객체의 변수와 함수를 숨기는 작업을 말합니다.
인스턴스 변수와 인스턴스 함수 앞에 __를 붙이면 외부에서 접근이 불가능해집니다.
이를통해 외부로부터 잘못된 객체가 들어오는 것을 차단할 수 있어 유지보수성이 좋아집니다.

아래와 같이 반지름을 통해 둘레와 넓이를 구하는 코드를 살펴보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Circle:
    def __init__(self, r):
        if r < 0:
            raise TypeError("반지름은 0 이상이어야 합니다.")
        self.r = r
        self.pi = 3.14
    def 둘레(self):
        return  2 * self.pi * self.r
    def 넓이(self):
        return self.pi * (self.r ** 2)


circle = Circle(10)
# circle = Circle(-10) # 음수일 경우 예외 오류 발생
circle.r = -10
print(circle.둘레()) # 둘레를 구함
print(circle.넓이()) # 넓이를 구함

circle객체를 생성할 때 매개변수를 음수로 생성하면 상기와 같이 raise를 사용하여 오류를 발생하게 할 수 있습니다.
그런데 인스턴스 변수를 음수로 바꿔버리면 오류가 발생하지않고 음수가 출력되는 상황이 발생합니다.
이러한 접근을 차단하기위해 인스턴스 변수와 인스턴스 함수 앞에 __를 붙여 외부에 접근을 차단하는 캡슐화 작업을 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Circle:
    def __init__(self, r):
        if r < 0:
            raise TypeError("반지름은 0 이상이어야 합니다.")
        self.__r = r
        self.__pi = 3.14
    def 둘레(self):
        return  2 * self.__pi * self.__r
    def 넓이(self):
        return self.__pi * (self.__r ** 2)


circle = Circle(10)
# circle = Circle(-10) # 음수일 경우 예외 오류 발생
print(circle.둘레()) # 둘레를 구함
print(circle.넓이()) # 넓이를 구함

캡슐화로 접근이 차단된 변수의 값을 추출하거나 할당할때는 get함수와 set함수를 만들어서 사용합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Circle:
    def __init__(self, r):
        if r < 0:
            raise TypeError("반지름은 0 이상이어야 합니다.")
        self.__r = r
        self.__pi = 3.14
    def get_r(self):
        return self.__r
    def set_r(self, value):
        if value < 0:
            raise TypeError("반지름은 0 이상이어야 합니다.")
        self.__r = value
    def 둘레(self):
        return  2 * self.__pi * self.__r
    def 넓이(self):
        return self.__pi * (self.__r ** 2)


circle = Circle(10)
print(circle.get_r())  # 반지름 출력
circle.set_r(20)  # 반지름을 20으로 변경
print(circle.둘레()) # 둘레를 구함
print(circle.넓이()) # 넓이를 구함


상속


상속은 class A(B): 처럼 표현할 수 있으며,
특정 메소드가 A 클래스에 없다면 B 클래스에서 메소드를 찾아 반영합니다.
만약 B 클래스도 class B(C): 형식이라면 B 클래스에서도 찾는 메소드가 없으면 C 클래스에서 메소드를 찾습니다.
A는 자식클래스(서브클래스), B는 부모클래스(슈퍼클래스)라고 칭합니다.
상속을 이용하면 중복되는 메소드를 간편하게 만들 수 있습니다.
또한, 부모클래스에 예외 오류를 생성하여 자식클래스의 필요한 부분을 찾아 입력할 수 있습니다.

만약 class A(B):에서 특정메소드가 A(자식클래스)에 있다면,
B(부모클래스)에 있는 동일한 메소드를 호출하지 않게됩니다. 이를 오버라이드(재정의)라고 합니다.
위와같이 특정메소드가 자식클래스에 있을때,
부모클래스에 있는 메소드를 사용하고싶다면 super()함수를 사용하여 호출할 수 있습니다.
super().메소드()형식으로 코드를 구현하면 부모클래스(슈퍼클래스)의 메소드를 호출할 수 있습니다.


This post is licensed under CC BY 4.0 by the author.