Magic Method (Special Method)

 파이썬에서는 객체에서 불러올 수 있는 메소드 중 __메소드이름__ 이런 식으로 더블언더스코어가 양쪽으로 붙어있는 메소드들이 있습니다.  이들은 매직 메소드 (혹은 스페셜 메소드, 혹은 던더 메소드) 라고 합니다.

 파이썬의 매직메소드는 프로그래머에 의해 직접적으로 쓰이기 보다는 객체에 어떤 액션을 취하느냐에 따라 클래스에서 내부적으로 처리됩니다.

 예를 들면, 우리는 a 와 b의 값을 더할때 a + b라고 표기합니다. 그런데 사실 a + b는 a 객체가 가지고 있는 메소드 __add__()에 의해 실행됩니다.

a+b
# 위 아래 코드는 동일
a.__add__(b)

 

각 객체가 가지고 있는 매직메소드는 dir() 를 통해 확인할 수 있습니다.

print(dir(int))

# ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', 
# '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', 
# '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', 
# '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', 
# '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', 
# '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', 
# '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', 
# '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', 
# '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', 
# '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', 
# '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', 
# '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio', 'bit_length', 
# 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

 

Magic Method (Special Method)의 쓰임새

오퍼레이터 기능 커스터마이징

파이썬의 오퍼레이터에 대한 오버로딩을 구현할 수 있도록 돕습니다. 즉, 사용자 정의의 클래스가 빌트인 오퍼레이터 기능을 커스터마이즈해서 사용할 수 있습니다.

예시) 기본 빌트인 타입 중 int와 string은 + 연산이 불가능하죠.

x = int(1)
print(x + '1')

# 결과: TypeError: unsupported operand type(s) for +: 'int' and 'str'

임의의 클래스를 구현하여 매직메소드를 사용하면 int와 string의 + 연산결과를 얻을 수 있습니다.

#int를 부모클래스로 가진다
class Customized(int): 
# 👇str input을 받아 + 연산을 하면 str 타입으로 합체
    def __add__(self, plus: str) -> str: 
        return str(self.real) + plus

x = Customized(1)
print(x + '1')

#결과: '11'

 

인스턴스 생성

 가장 유명한 던더 메소드는 아마 __init__()일 것입니다. 그리고 __init__()과 함께 constructor 역할을 하는 __new__()라는 메소드가 있습니다. __new__()라는 메소드는 새로운 인스턴스를 생성하고 (return하고), __init__()이 return된 인스턴스를 인자에 맞게 커스터마이즈(초기화)합니다. __new__() 는 static method이며, 일반적인 경우 굳이 오버라이드 하지 않습니다.

형식과 사용법은 아래와 같습니다.

#__new__() 형식

class ClassName:
    def __new__(cls, *args, **kwargs):
        #...중간 코드...#
        return super(ClassName, cls).__new__(cls, *args, **kwargs)
# 적용 예시

class MyClass(object):
    def __new__(cls, interger:int, array:list):
        print('인스턴스 생성중...')
        return super(MyStr, cls).__new__(cls, interger, array)

    def __init__(self, interger, array):
        self.interger = interger
        self.array = array

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

[Python] Decorator  (0) 2022.05.20
[Python] Example of Magic Method  (0) 2022.05.13
[Python] Method Type  (0) 2022.05.10
[Python] Closer  (0) 2022.05.02
[Python] 일급 객체 (First-Class Citizen)  (0) 2022.04.30

+ Recent posts