본문 바로가기
Language/Python

[Python] 매직 메서드(Magic Method)

by 며루치꽃 2021. 10. 24.

전문적인 정보를 다루는 것이 아닌 개인적으로 학습한 내용에 대해

포스팅을 했기 때문에 이점을 감안하여 봐주시면 감사하겠습니다👏

 

매직 메서드(Magic Method)

클래스 안에 정의할 수 있는 특별한(Built-in) 메서드입니다. 때론, 스페셜 메서드(Special Method)로 불리기도 합니다. 

특별하다는 의미(?): 이미 만들어진 것을 예를 들어,

3 + 3 을 했을 때, 6이 나오는 것처럼 어떤 특별한(Built-in) 메서드가 동작을 해서, 결과값이 6이 나오는 것인지, 

좀 더 낮은 레벨에서, 클래스 기반으로 코딩을 할 수 있도록 도와주는 메서드

 

매직 메서드를 이해해야 클래스를 좀 더 풍부하게 사용하고, 시퀀스를 이해해야 반복과 함수를 좀 더 편리하게 사용할 수 있습니다. 

print(int) # class

파이썬에서 지금까지 int, str 등은 모두 클래스 타입입니다. 클래스이기 때문에 __ 로 시작하는 메서드들이 이미 정의가 되어 있습니다. 

 

n = 10
print(type(n))

변수를 정의하고 type을 print 해보면 다음과 같이 class 로 정의되어있는 것을 확인할 수 있습니다. 이미 만들어져있는 메서드들을 구현해주기만 하면, 좀 더 low 레벨에서 개발할 수 있습니다.

 

print(n + 100)

다음과 같이 작성하였을 때 결과는 110이 나오게 됩니다. 이는 내부적으로 __add__ 가 호출되었다는 의미입니다.

print(n.__add__(100))

매직메소드를 이용하여 작성하여보면 결과값이 똑같은 것을 알 수가 있습니다. 비슷한 예시로 다음의 예시를 들 수 있습니다.

print(n.__bool__(), bool(n)) # 0이 아니므로 True가 나옵니다.

n은 클래스이고 built-in 메서드를 사용하여 __bool__ 이 동작하게 되어 결과값은 True가 나오게 됩니다.

 

파이썬은 사람들이 개발하기 쉽게 랩핑(rapping)을 해서, 내부적으로 호출되는 언어로 호출되서 사용할 수 있고, 또 int() 처럼 나만의 메서드를 만들수 있습니다.


 

매직 메서드 예제

class Fruit:
    def __init__(self, name, price):
        self._name = name
        self._price = price

    def __str__(self):
        return 'Fruit Class Info : {} , {}'.format(self._name, self._price)
    
    def __add__(self, x): # 클래스 기반으로 더하기 할 수 있다
        return self._price + x._price 

# 인스턴스 생성
s1 = Fruit('Orange', 7500)
s2 = Fruit('Banana', 3000)

다음과 같이 클래스를 선언하고, 인스턴스 2개를 만들어보았습니다. 

만약 매직 메서드를 모른다면 다음과 같이 작성을 해야합니다.

print(s1._price + s2._price)

하지만, __add__ 매직 메서드를 구현해놓았기 때문에 아래와 같이 구현할 수 있습니다.

print(s1 + s2) # 10500

보통 연산자 '+' 를 사용하는 것은, 정수, 소수 형태를 더하는 연산자이지만, 매직 메소드를 구현하면 내부적으로 __add__ 메서드가 호출되면서 우리가 구현하고자 하는 매직 매서드를 구현하였습니다.

 

def __add__(self, x): # 클래스 기반으로 더하기 할 수 있다
	return (self._price + x._price ) * 0.8
    
print(s1 + s2) # 8400.0

매직 메서드를 다음과 같이 구현하고, '+' 연산자를 사용하였을 때 내가 정해놓은 수식을 통해서 결과값을 도출해낼 수 있습니다. 

 

class Fruit:
    def __init__(self, name, price):
        self._name = name
        self._price = price

    def __str__(self):
        return 'Fruit Class Info : {} , {}'.format(self._name, self._price)
    
    def __add__(self, x): # 클래스 기반으로 더하기 할 수 있다
        return (self._price + x._price ) * 0.8

    def __sub__(self, x):
        return self._price - x._price

    def __le__(self, x):
        print('Called >> __le__')
        if self._price <= x._price:
            return True
        else:
            return False

    def __ge__(self, x):
        print('Called >> __ge__')
        if self._price >= x._price:
            return True
        else:
            return False

매직 메서드 실행 결과는 아래와 같습니다.

 

print(s1 >= s2) # True
print(s1 <= s2) # False
print(s1 - s2) # 4500
print(s2 - s1) # -4500
print(s1) #__str__
print(s2) #__str__

 

 

매직 메서드를 이용하여 클래스 기반으로 코딩할 수 있습니다.

댓글