파이썬의 매직 메소드

파이썬의 매직 메소드

이 글에서는 파이썬의 매직 메소드에 대해 설명합니다.

YouTube Video

파이썬의 매직 메소드

파이썬의 매직 메소드(특수 메소드)는 클래스에 고유한 동작을 부여하기 위해 특별히 명명된 메소드입니다. 예를 들어 __init__이나 __str__처럼 더블 언더스코어(dunder)로 감싸져 있다는 특징이 있습니다. 따라서 dunder 메소드라고도 불립니다.

매직 메소드를 정의함으로써 클래스의 표준 동작을 커스텀할 수 있습니다. 예를 들어 __add__를 정의하면 + 연산자의 동작을 변경할 수 있습니다.

초기화와 문자열 표현을 위한 매직 메소드

__init__: 초기화 메소드

__init__ 메소드는 인스턴스가 생성될 때 자동으로 호출되는 생성자입니다.

1class Person:
2    def __init__(self, name, age):
3        self.name = name
4        self.age = age
5
6person = Person("Alice", 30)
7print(person.name)  # Alice

__str__: 사람이 읽기 쉬운 문자열 표현

__str__ 메소드는 사람이 읽기 쉬운 문자열 표현을 반환합니다. 이 메소드는 print()str()에서 호출됩니다.

1class Person:
2    def __init__(self, name):
3        self.name = name
4
5    def __str__(self):
6        return f"Person: {self.name}"
7
8person = Person("Bob")
9print(person)  # Person: Bob

__repr__: 디버깅 목적의 문자열 표현

__repr__ 메소드는 디버깅을 위한 문자열 표현을 반환합니다. repr() 함수나 인터프리터에서 객체를 표시할 때 사용됩니다.

1class Person:
2    def __init__(self, name):
3        self.name = name
4
5    def __repr__(self):
6        return f"Person(name={self.name!r})"
7
8person = Person("Eve")
9print(repr(person))  # Person(name='Eve')

산술 연산자 오버로딩

__add__: + 연산자

매직 메소드를 이용하면 산술 연산자를 오버로딩할 수 있습니다. 예를 들어, __add__ 메소드로 + 연산자를 오버로딩할 수 있습니다.

 1class Vector:
 2    def __init__(self, x, y):
 3        self.x = x
 4        self.y = y
 5
 6    def __add__(self, other):
 7        return Vector(self.x + other.x, self.y + other.y)
 8
 9    def __repr__(self):
10        return f"Vector({self.x}, {self.y})"
11
12    # Other arithmetic magic methods:
13    # def __sub__(self, other):       # Subtraction (-)
14    # def __mul__(self, other):       # Multiplication (*)
15    # def __truediv__(self, other):   # True division (/)
16    # def __floordiv__(self, other):  # Floor division (//)
17    # def __mod__(self, other):       # Modulo (%)
18    # def __pow__(self, other):       # Exponentiation (**)
19
20v1 = Vector(1, 2)
21v2 = Vector(3, 4)
22print(v1 + v2)  # Vector(4, 6)

기타 산술 관련 매직 메소드는 다음과 같습니다:.

메소드 연산자
__add__ +
__sub__ -
__mul__ *
__truediv__ /
__floordiv__ //
__mod__ %
__pow__ **

비교 연산자 커스터마이즈

비교 연산자도 오버로딩할 수 있습니다. 예를 들어, __eq__ 메소드는 동등 연산자를 오버로딩합니다.

 1class Box:
 2    def __init__(self, volume):
 3        self.volume = volume
 4
 5    def __eq__(self, other):
 6        return self.volume == other.volume
 7
 8    def __lt__(self, other):
 9        return self.volume < other.volume
10
11    # Comparison magic methods:
12    # def __eq__(self, other):  # Equal to (==)
13    # def __ne__(self, other):  # Not equal to (!=)
14    # def __lt__(self, other):  # Less than (<)
15    # def __le__(self, other):  # Less than or equal to (<=)
16    # def __gt__(self, other):  # Greater than (>)
17    # def __ge__(self, other):  # Greater than or equal to (>=)
18
19b1 = Box(100)
20b2 = Box(200)
21
22print(b1 == b2)  # False
23print(b1 < b2)   # True

다음과 같은 매직 메소드도 있습니다:. 이러한 매직 메소드는 객체 간의 동등성이나 순서를 정의합니다.

연산자 매직 메소드
== __eq__
!= __ne__
< __lt__
<= __le__
> __gt__
>= __ge__

컨테이너 타입을 위한 매직 메소드

리스트나 딕셔너리처럼 동작하는 클래스를 만들 수 있습니다.

__len__: 요소 개수 가져오기

__len__ 메소드는 요소의 개수를 반환하는 매직 메소드입니다.

1class Basket:
2    def __init__(self, items):
3        self.items = items
4
5    def __len__(self):
6        return len(self.items)
7
8basket = Basket(["apple", "banana"])
9print(len(basket))  # 2

__getitem__: 인덱스 접근

__getitem__ 메소드는 인덱스로 접근할 때 호출됩니다.

1class Basket:
2    def __init__(self, items):
3        self.items = items
4
5    def __getitem__(self, index):
6        return self.items[index]
7
8basket = Basket(["apple", "banana"])
9print(basket[1])  # banana

__setitem__, __delitem__: 값 쓰기 및 삭제

__setitem____delitem__ 메소드는 아이템을 쓰거나 삭제할 때 호출됩니다.

 1class Basket:
 2    def __init__(self, items):
 3        self.items = items
 4
 5    def __setitem__(self, index, value):
 6        self.items[index] = value
 7
 8    def __delitem__(self, index):
 9        del self.items[index]
10
11basket = Basket(["apple", "banana"])
12basket[1] = "grape"
13del basket[0]
14print(basket.items)  # ['grape']

반복을 위한 매직 메소드

for 루프에서 객체를 반복 가능하게 하려면 다음을 구현합니다:.

__iter____next__

 1class Counter:
 2    def __init__(self, limit):
 3        self.limit = limit
 4        self.current = 0
 5
 6    def __iter__(self):
 7        return self
 8
 9    def __next__(self):
10        if self.current >= self.limit:
11            raise StopIteration
12        self.current += 1
13        return self.current
14
15for num in Counter(3):
16    print(num)
17# Output:
18# 1
19# 2
20# 3

컨텍스트 매니저 (with 문)

__enter____exit__ 메소드를 정의하면 with 문에서 전후 처리를 구현할 수 있습니다.

 1class FileOpener:
 2    def __init__(self, filename):
 3        self.filename = filename
 4
 5    def __enter__(self):
 6        self.file = open(self.filename, 'r')
 7        return self.file
 8
 9    def __exit__(self, exc_type, exc_val, exc_tb):
10        self.file.close()
11
12with FileOpener("example.txt") as f:
13    content = f.read()
14    print(content)

호출 가능한 객체: __call__

__call__ 메소드를 정의하면 인스턴스를 함수처럼 호출할 수 있습니다.

1class Greeter:
2    def __init__(self, greeting):
3        self.greeting = greeting
4
5    def __call__(self, name):
6        return f"{self.greeting}, {name}!"
7
8hello = Greeter("Hello")
9print(hello("Alice"))  # Hello, Alice!

요약

파이썬의 매직 메소드는 클래스에 자연스럽고 직관적인 동작을 추가할 수 있는 강력한 방법입니다. 각 매직 메소드는 명확한 목적이 있으며, 이를 적절히 구현하면 더욱 유연하고 파이썬다운 코드를 작성할 수 있습니다.

매직 메소드는 파이썬 객체들이 보이지 않는 인터페이스로서 내부적으로 상호작용하고 동작하도록 지원합니다.

위의 기사를 보면서 Visual Studio Code를 사용해 우리 유튜브 채널에서 함께 따라할 수 있습니다. 유튜브 채널도 확인해 주세요.

YouTube Video