본문 바로가기
Python

[Python] special methods and operator overloading

by ds31x 2023. 7. 13.

Special Methods

사용자가 직접 호출하는 경우가 거의 없고, 간접적으로 호출이 됨.

즉, 개발자(사용자)가 over-riding을 통해 구현은 하지만 직접 호출하는 경우가 거의 없고,
개발자가 다른 built-in function이나 operator를 호출할 때, 내부적으로 
Python interpreter에 의해 호출되는 methods를 가르킴.

  • 특징으로 double underscore __ 로 이름이 시작되고 끝난다 ( double underscores를 dunder라고도 부름.)

double underscore로 싸여있는 이름은
Python이 다른 syntax와 연결되어 사용되도록
미리 정해놓은 method나 variable들(=Python internal variables or methods)임
을 나타내기 위해 사용된다.
때문에 프로그래머는
자신이 만든 class나 function, varaible 등의 이름을
double underscore로 시작하고 끝나도록 해서는 안된다.


많은 경우, special methods는 다음의 두가지 경우에서 호출됨.

  • 특정 built-in function이 호출될 때,
    해당 built-in function의 argument로 넘겨진 object의 대응하는 special method가 호출.
  • 특정 operator들이 사용될 때, operand로 넘겨진 object의 대응하는 special method가 호출.

첫번째 경우의 대표적인 예로 Built-in function len(collection_obj)의 경우와 print(obj_to_print)의 경우를 들 수 있다.

  • len(collection_obj) 호출의 경우,
    argument로 넘겨진 collection_obj의 item의 수를 반환하는데
    실제로는 collection_obj의 special method __len__()을 호출로 이어진다.
  • print(obj_to_print) 호출의 경우,
    obj_to_print에 대한 문자열이 출력되는데,
    해당 문자열은 사실 obj_to_print__str__() special method가 호출되어 반환값으로 얻어진 문자열이다.
  • python interaction shell에서 object를 기재하고 enter를 누르면
    해당 object에 대한 값이 출력되는데,
    이 값에 해당하는 문자열은 기재된 object의 special method인 __repr__()이 호출되어 얻어진다.

 

다음의 예는 len__len__의 관계를 보여줌.

>>> a = [1,2,3,4,5]
>>> c = len(a) # c = a.__len__()
>>> print(c)
5
>>> a # a.__repr__()
[1,2,3,4,5]

두번째 경우의 대표적인 예로는 list 객체에서 + operator를 통해 list가 합쳐지는 것과 문자열 간에 + operator를 통한 concatenation 수행을 들 수 있다.

  • a += [2,3] 에서 alist object이면, 실제로 a.__iadd__([2,3])이 호출되게 된다.
  • c = 'abc'+'def''abc'.__add__('def') 가 호출되어 해당 반환값이 c에 할당됨.
  • a>b 의 경우도 실제론 a.__gt__(b) 가 호출되어 boolean 반환값이 얻어진다.
a = [5,6,7]
a += [2,3] # a.__iadd__([2,3])
print(a)

위의 예에서 보이듯이,

  • special method는 프로그래머가 명시적으로 직접 호출하기 보다는 다른 함수 등의 호출을 통해 간접적으로 호출이 된다.
  • 물론 직접 호출도 가능하지만 일반적으로 그렇게 사용하는 경우는 거의 없다.

참고로 Python에서 class를 정의할 때, 만드는 생성자 __init__ 역시 해당 class의 instance를 생성할 때 알아서 호출이 이루어진다.


대표적 Special Methods 와 Operator Overloading

Python은 numeric data type을 비롯하여 모든 것이 object이기 때문에

  • 사용되는 다양한 operator의 operand로 object들이 주어진 경우 
  • 해당 object의 특정 special method가 호출되도록 구성이 가능하다.

 

Python에서 많은 operator들은
operand의 type에 따라 다르게 동작 (operator overloading의 경우)하는데,
이를 가능하게 해주는 것이 바로 special method이다.

 

이를 통해 operand의 object의 class에 따라 다른 기능으로 동작하도록 기존의 operator를 중복으로 정의가 가능하며 이를 Operator Overloading 이라고 부림.

 

이때 사용되는 대표적인 special methods는 다음과 같음.

비교 연산을 위한 special method names
__eq__ (self,other) self == other
__ne__ (self,other) self != other
__lt__ (self,other) self < other
__gt__ (self,other) self > other
__le__ (self,other) self <= other
__ge__ (self,other) self >= other
산술 연산을 위한 special method names
__add__ (self,other) self + other
__sub__ (self,other) self +- other
__mul__ (self,other) self * other
__floordiv__ (self,other) self // other
__truediv__ (self,other) self / other
__mod__ (self,other) self % other
__pow__ (self,other) self ** other
__radd__ (self,literal) literal + self
__rsub__ (self, literal) literal - self
__rmul__ (self, literal) literal * self
  • `3+obj` 와 같이 literal이 앞의 operand로 주어질 경우에는 reverse의 r이 붙은 special methods를 구현해야 함.
in-place 연산을 위한 special method names  
__iadd__ (self, other) self += other
__isub__ (self, other) self -= other
__imul__ (self, other) self *= other
  • in-place (or augmented assignment) operator에 대한 speical methods들은 이름에 i가 붙게 된다. 
단항 연산을 위한 special methods names
__pos__ (self) + self
__neg__ (self) - self
__invert__ (self) ~ self
__abs__ (self) abs(self)
기타 special method names
__str__ (self) str(self)
__repr__ (self) repr(self)
__len__ (self) len(self)
__call__ (self) self()
__iter__ (self) iter(self)
__next__ (self) next(self)
  • __call__ (self) 가 구현된 object를 가르켜 callable 이라고 함.
  • __iter__ (self) 가 구현된 object를 가르켜 iterable 이라고 함.
  • __next__ (self) 가 구현된 object를 가르켜 iterator 라고 함.

 

Operator overloading은 Python syntax에서 많이 사용된 기법이라

python의 동작을 이해하는 데에는 중요한 개념에 속하지만,

해당 기능 자체를 이용하여 custom class에 적용하는 것은 개인적으로 권장하지 않는다.

 

일단 syntax에 대한 직관적인 이해가 되는 것들의 경우, 대부분 기본 동작으로 구현이 되어 있기 때문에

굳이 custom class를 연산자로 처리하는 건 공동작업자들의 code 가독성을 떨어뜨리기 쉽다. 

 

operator의 관점에서는 같은 이름이나 argument에 해당하는 operand 의 종류에 따라 다른 기능을 수행되도록 만든 것이라 operator overloading 으로 불리지만, 이에 대한 구현은 special method를 overriding하는 것이라는 점을 기억해둔다면 이후 다양한 3rd party library등을 이해하는데 도움이 된다.

2023.07.13 - [Python] - [Python] overloading, overriding, and special methods

 

[Python] overloading, overriding, and special methods

일반적인 Overloading overloading (or over-load, 과적?)이란 같은 이름의 function, method, operator를 여러 개로 중복 정의하는 것을 가르킴. function의 경우, call시 입력되는 arguments가 할당될 parameters를 다르게

ds31x.tistory.com