본문 바로가기

Study doc./Python

[Python] 파이썬 클래스, 이거 한 번만 읽어봐!

Q. 야, 클래스가 뭐야? 왜 필요해?

 

A. 썼던 내용들 반복 안하려고! 미리 정의해두고 필요할 때만 호출해서 쓰려고!

 

 

Q. 그럼 그냥 함수를 만들어서 쓰면 되잖아!!

 

A. 맞아, 근데 클래스가 함수들을 모아둔거야! 

    머신러닝 알고리즘 써봤어? 로지스틱 알고리즘 사용할 때 model = LogisticRegression() 쓴거 기억나?

    이게 사실은 LogisticRegression 이라는 클래스를 호출해서 model이라는 객체에 넣은거야.

    그리고 model.fit(X_train, y_train) 했었지? 여기서 fit이 LogisticRegression 클래스 안에 있던 하나의 함수였던거지!

 

 

Q. 야, 어떤 사람이 클래스 쓴거 봤는데 init이랑 양옆에 underbar( __ )랑 self랑 처음 보는 문법들 있더라.

    너무 복잡해서 포기했는데, 이거 어려운 문법 맞지?

 

A. 하나도 안어려워! 쉽게 이해할 수 있게 클래스를 만들면서 설명해줄게.

    사칙연산을 할 수 있는 클래스를 만들어보자!

 

    첫 번째로 클래스를 만들자

 

class Calculator:

 

    두 번째로 사칙연산에 사용될 숫자를 변수로 저장해야지!

    기존에 만들었던 함수 같았으면 이렇게 했을거야!!

 

def make_num(a,b):
    num1 = a
    num2 = b

 

    하지만 우리는 그냥 클래스를 호출하자마자 변수를 저장하고 싶어!

    그래서 나온게 init이야.

    양 옆으로 underbar 가 있는건 사람들이 우연이라도 이걸 함수로써 호출하게 되는걸 방지하기 위해서야!

    아무튼 init은 클래스가 호출되면 동시에 자동으로 돌아가는 함수라고 보면 돼! 

    한 번 구현해보자

 

class Calculator:
    def __init__(a,b):
        num1 = a
        num2 = b
        
    def sum():
        result = num1 + num2
        return result
    
    def sub():
        result = num1 - num2
        return result

 

    이제 덧셈과 뺄셈을 사용할 수 있을까?

    아니, 한가지 더 남았어.

    클래스에서 함수를 만들 때에는 self 라는 매개변수를 넣어줘야해.

 

    이게 무슨 의미냐면, 클래스를 호출할때 객체를 생성하잖아( ex. model = LogisticRegression() ).

    그럼 "그 객체에서" 사용하는 함수라는걸 써줘야해

    하지만 그 객체 이름을 너가 뭐라고 할지 모르니깐 self 라고 만든거야.

 

    예를 들어 "self.num1 = a" 는 "클래스를 호출한 객체의 num1에 a라는 값을 넣겠다" 라는 말이지.

    아직 이해가 안간다면 아래 만든 코드를 봐!!

 

class Calculator:
    def __init__(self,a,b):
        self.num1 = a
        self.num2 = b
        
    def sum(self):
        result = self.num1 + self.num2
        return result
    
    def sub(self):
        result = self.num1 - self.num2
        return result

 

자, 이런식으로 곱하기, 나누기를 추가해주면 되는데,

더 깊이 공부하기 위해 상속을 통해 추가해줄거야.

클래스를 상속받으면 상속한 클래스의 함수들을 별다른 코드 없이 사용할 수 있어.

바로 보여줄게!

 

class final_calculator(Calculator):
    def mul(self):
        result = self.num1 * self.num2
        return result
    
    def div(self):
        result = self.num1 / self.num2
        return result

 

이제 final_calculator 클래스를 통해 모든 사칙연산을 다 수행할 수 있다!!

 

추가로 상속한 클래스(Calculator)의 메서드를 상속 받은 클래스(final_calculator)에서 수정할 수도 있는데,

이를 메서드 오버라이딩이라고 해.

예를 들어 빼기 연산을 final_calculator 에서는 절댓값을 씌운 형태로 수정하고 싶다면 이렇게 하면 돼.

 

class final_calculator(Calculator):
    def sub(self):
        result = abs(self.num1 - self.num2)
        return result
        
    def mul(self):
        result = self.num1 * self.num2
        return result
    
    def div(self):
        result = self.num1 / self.num2
        return result

 

마지막으로 연산자 오버로딩만 설명해줄게.

이건 객체끼리 사칙연산을 했을때 어떻게 할지 정해주는거야.

그리고 그 약속을 이렇게 표현하기로 약속했어.

 

+ : __add__

- : __sub__

* : __mul__

/ : __truediv__

 

예를 들어 우리는 두 객체를 곱했을때 내적 연산을 수행하게 하고 싶어.

그럼 이렇게 하면 되겠지?

 

class final_calculator(Calculator):
    def sub(self):
        result = abs(self.num1 - self.num2)
        return result
        
    def mul(self):
        result = self.num1 * self.num2
        return result
    
    def div(self):
        result = self.num1 / self.num2
        return result
    
    def __mul__(self, other):
        result = (self.num1 * other.num1) + (self.num2 * other.num2)
        return result

 


 

최종 코드

class Calculator: 
    def __init__(self,a,b): # 객체 생성시 자동 실행
        self.num1 = a 
        self.num2 = b 
         
    def sum(self): 
        result = self.num1 + self.num2 
        return result 
     
    def sub(self): 
        result = self.num1 - self.num2 
        return result

class final_calculator(Calculator): # 상속
    def sub(self): # 메서드 오버라이딩
        result = abs(self.num1 - self.num2) 
        return result 
         
    def mul(self): 
        result = self.num1 * self.num2 
        return result 
     
    def div(self): 
        result = self.num1 / self.num2 
        return result 
     
    def __mul__(self, other): # 연산자 오버로딩
        result = (self.num1 * other.num1) + (self.num2 * other.num2) 
        return result