파이썬의 클래스에서 사용하기 위한 특수한 메소드다. 매직 메소드라고 부른다.
이러한 매직 메소드들은 이미 정해진 메소드를 오버로딩해 클래스만의 특별한 기능으로 사용할 수 있다.
매직 메소드의 특징으론 앞뒤에 언더바 두개를 가지고 있다. ex) __add__
__init__
클래스가 생성될때 초기화를 진행하게 되는 메소드다.
클래스를 생성할때 사용한 파라미터를 메소드의 파라미터로 전달받게 된다.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def who(self):
print(f"이름 : {self.name}, 나이 : {self.age}")
kim = Person("kim", 25)
kim.who()
객체 생성시 파라미터로 전달된 "kim", 25라는 값이 __init__ 메소드의 파라미터로 전달되게 된다.
__repr__, __str__
클래스를 출력할때 사용한다. 자바의 toString()과 유사하다.
두 메소드 모두 클래스를 문자열로 보여주기 위한 메소드지만 약간의 차이가 존재한다.
__repr__의 목적은 객체를 표현하기 위함이다.
__str__의 목적은 객체를 유니버셜한 인터페이스인 "문자열"로 변환하기 위함이다.
__repr__은 객체의 "공식적인" 문자열 표현이다.
__str__은 객체의 "비공식적인" 문자열 표현이다.
__repr__은 __str__보다 더욱 딱딱한 표현이라 볼 수 있다.
__repr__은 __str__보다 포말한 정보를 담아야 한다.
__repr__은 개발자를 위한 표현, __str__은 사용자를 위한 표현이라 볼 수 있다.
__repr__, __str__ 예제
class A:
def __init__(self, n):
self.n = n
def __str__(self):
return f'{self.n}'
def __repr__(self):
return f'{self.n * self.n}'
생성시 n 을 받아 __str__메소드는 n을 리턴하고, __repr__메소드는 n 제곱을 리턴한다.
1. 둘다 없는 경우
두 메소드가 없다면 해당 클래스로 만든 객체는 출력시 다음과 같은 출력을 보인다.
class A:
def __init__(self, n):
self.n = n
# def __str__(self):
# return f'{self.n}'
# def __repr__(self):
# return f'{self.n * self.n}'
a = A(3)
print(a)
2. __repr__만 있는경우
__repr__만 있는경우 객체 출력시 __repr__의 결과를 리턴한다.
class A:
def __init__(self, n):
self.n = n
# def __str__(self):
# return f'{self.n}'
def __repr__(self):
return f'{self.n * self.n}'
a = A(3)
print(a)
3. __str__만 있는경우
__str__만 있는경우 객체 출력시 __str__의 결과를 리턴한다.
class A:
def __init__(self, n):
self.n = n
def __str__(self):
return f'{self.n}'
# def __repr__(self):
# return f'{self.n * self.n}'
a = A(3)
print(a)
4. 둘 다 있는경우
둘 다 있는경우 __str__의 결과를 리턴한다 (일반적인 문자열 출력상황 print, str 함수의 결과)
class A:
def __init__(self, n):
self.n = n
def __str__(self):
return f'{self.n}'
def __repr__(self):
return f'{self.n * self.n}'
a = A(3)
print(a)
__len__
len() 메소드를 통해 객체의 크기를 얻을때 실행된다.
class A:
def __init__(self, n):
self.n = n
def __len__(self):
return self.n
a = A(3)
print(len(a))
len() 메소드를 실행하면 객체의 n 값을 리턴해주게 된다.
print의 결과는 3이 나오게 된다
__contains__
in 연산수행할때 실행된다. in의 피연산자가 __contains__의 파라미터로 전달된다. 리턴값은 bool 형이다.
class A:
def __init__(self, n):
self.n = n
def __contains__(self, n):
return self.n == n
a = A(3)
print(3 in a)
a 객체의 contains 메소드는 피연산자와, n 값을 비교해 리턴하므로 True가 리턴된다.
__del__
객체가 소멸되는 시점에 실행된다.
class A:
def __init__(self, n):
print("init")
self.n = n
def print_n(self):
print(f"n : {self.n}")
def __del__(self):
print("del")
a = A(3)
a.print_n()
del a
__del__ 메소드는 객체가 소멸되는 시점에 실행된다.
연산 메소드
+, -, > 등 연산자와 관련된 메소드또한 오버라이딩 할 수 있다.
별다른 메소드가 없는 클래스의 경우 객체끼리의 + 연산의 결과는 오류가 나게된다.
class A:
def __init__(self, n):
self.n = n
a = A(3)
b = A(4)
print(a + b)
하지만 __add__ 메소드를 오버라이딩 해주게 된다면, 객체간 + 연산이 가능해진다.
class A:
def __init__(self, n):
self.n = n
def __add__(self, T):
return self.n + T.n
a = A(3)
b = A(4)
print(a + b)
"+" (__add__) 뿐 아니라 "-" (__sub__), "*" (__mul__) 등 다양한 연산도 오버라이딩해 사용할 수 있다.