본문 바로가기

파이썬 매직 메소드

파이썬의 클래스에서 사용하기 위한 특수한 메소드다. 매직 메소드라고 부른다.

이러한 매직 메소드들은 이미 정해진 메소드를 오버로딩해 클래스만의 특별한 기능으로 사용할 수 있다.

매직 메소드의 특징으론 앞뒤에 언더바 두개를 가지고 있다. 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__) 등 다양한 연산도 오버라이딩해 사용할 수 있다.