상세 컨텐츠

본문 제목

매직 메서드

인공지능_2026/1. 파이썬

by Ryuzy 2026. 4. 30. 11:41

본문

반응형

매직 메서드(magic method)는 파이썬에서 특정 문법이나 연산이 실행될 때 자동으로 호출되는 특별한 메서드로, __len__, __str__, __getitem__처럼 양쪽에 밑줄(__)이 붙는 형태를 가집니다. 이 메서드들을 클래스에 구현하면 len(obj), print(obj), obj[0], obj + obj 같은 파이썬의 기본 문법과 자연스럽게 연결되어 객체의 동작을 직접 정의할 수 있습니다. 즉, 매직 메서드는 객체를 리스트처럼 사용하거나, 연산을 수행하거나, 출력 형태를 바꾸는 등 파이썬의 문법과 객체를 이어주는 핵심 기능입니다.

 

1. 객체 출력

1. __str__()

__str__()는 객체를 사람이 읽기 쉬운 문자열로 표현하기 위해 사용하는 매직 메서드로, print(obj)나 str(obj)가 호출될 때 자동으로 실행됩니다. 이 메서드를 클래스에 정의하면 객체를 출력할 때 기본 주소값 대신 원하는 형태로 내용을 보여줄 수 있어 디버깅이나 사용자 출력에 매우 유용합니다.

class Fruit:
    def __init__(self, name, quantity):
        self.name = name
        self.quantity = quantity

    def __str__(self):
        return f"{self.name} {self.quantity}개"

apple = Fruit("사과", 10)

print(apple)        # __str__ 호출
print(str(apple))   # __str__ 호출

 

2. __repr__()

__repr__()은 객체를 개발자 관점에서 정확하게 표현하는 문자열을 반환하는 매직 메서드로, 주로 디버깅이나 로그에서 사용됩니다. repr(obj)를 호출하거나 인터프리터에서 객체를 직접 평가할 때 자동으로 호출되며, 가능하다면 객체를 다시 생성할 수 있는 형태의 문자열을 반환하는 것이 권장됩니다. __str__()이 사람이 읽기 좋은 출력이라면, __repr__()은 객체의 구조와 상태를 명확하게 보여주는 공식적인 표현입니다.

class Fruit:
    def __init__(self, name, quantity):
        self.name = name
        self.quantity = quantity

    def __repr__(self):
        return f"Fruit(name='{self.name}', quantity={self.quantity})"

apple = Fruit("사과", 10)

print(repr(apple))  # __repr__ 호출
print(apple)        # __str__ 없으면 __repr__ 호출

 

 

2. 제너레이터

제너레이터(generator)는 yield 키워드를 사용해 값을 한 번에 하나씩 생성해 반환하는 반복 객체로, 함수 형태로 간단하게 이터레이터를 만들 수 있는 파이썬의 기능입니다. 일반 함수처럼 보이지만 yield를 만나면 값을 반환하면서도 실행 상태를 유지하고, 다음 호출 시 이어서 실행되기 때문에 전체 데이터를 한 번에 만들지 않고 필요할 때마다 생성할 수 있어 메모리 효율이 매우 높습니다.

class Counter:
    def __init__(self, max):
        self.max = max
        self.current = 0

    def __iter__(self):
        return self  # 자기 자신을 iterator로 사용

    def __next__(self):
        if self.current < self.max:
            self.current += 1
            return self.current
        else:
            raise StopIteration

counter = Counter(3)

for num in counter:
    print(num)

👉 for문이 내부적으로 자동으로 iter()를 호출합니다.

👉 이터레이터는 이터러블로부터 실제로 값을 하나씩 꺼내는 객체로, __iter__()와 __next__() 메서드를 모두 구현하고 있습니다.  __iter__()는 반복을 시작하게 하고, __next__()는 값을 하나씩 꺼내며, 더 이상 반환할 값이 없으면 StopIteration 예외를 발생시켜 반복을 종료합니다. 

 

def counter(max):
    current = 0
    while current < max:
        current += 1
        yield current

for num in counter(3):
    print(num)

👉 yield의 의미

1. 값을 반환한다
2. 함수 상태를 저장한다
3. 다음 호출 시 이어서 실행한다

👉 제너레이터는 자동으로 __iter__ + __next__를 만들어줍니다.

 

 

3. 인덱싱

1. __getitem__()

__getitem__()은 객체에서 인덱스나 키를 이용해 값을 조회할 때 호출되는 매직 메서드로, obj[index] 또는 obj[key] 형태로 접근하면 자동으로 실행됩니다. 이 메서드를 구현하면 사용자 정의 객체도 리스트나 딕셔너리처럼 데이터를 꺼낼 수 있으며, 내부적으로는 전달된 인덱스나 키를 기반으로 값을 반환하도록 작성하면 됩니다.

 

2. __setitem__()

__setitem__()은 객체에서 인덱스나 키를 이용해 값을 할당할 때 호출되는 매직 메서드로, obj[index] = value 형태의 코드가 실행되면 자동으로 호출됩니다. 이 메서드를 구현하면 사용자 정의 객체에 값을 저장하거나 수정하는 동작을 제어할 수 있으며, 전달된 인덱스와 값을 이용해 내부 데이터를 업데이트하도록 구현합니다

 

3. __delitem__()

__delitem__()은 객체에서 인덱스나 키를 이용해 값을 삭제할 때 호출되는 매직 메서드로, del obj[index] 형태의 코드가 실행되면 자동으로 호출됩니다. 이 메서드를 구현하면 사용자 정의 객체에서 특정 데이터를 삭제하는 로직을 정의할 수 있으며, 전달된 인덱스를 기반으로 내부 데이터를 제거하도록 작성합니다

 

class MyList:
    def __init__(self):
        self.data = []

    def __getitem__(self, index):
        return self.data[index]

    def __setitem__(self, index, value):
        self.data[index] = value

    def __delitem__(self, index):
        del self.data[index]


ml = MyList()

ml.data = [10, 20, 30]

print(ml[0])   # __getitem__ → 10

ml[1] = 99     # __setitem__
print(ml.data) # [10, 99, 30]

del ml[0]      # __delitem__
print(ml.data) # [99, 30]

 

 

4. 객체를 함수, 값처럼 사용

1. __call__()

__call__()은 객체를 함수처럼 호출할 수 있게 만들어주는 매직 메서드로, obj() 형태로 객체를 실행하면 자동으로 호출됩니다. 이 메서드를 구현하면 클래스 인스턴스가 일반 함수처럼 동작할 수 있으며, 내부 상태를 활용한 연산이나 처리 로직을 간결하게 표현할 수 있습니다.

class Multiplier:
    def __init__(self, n):
        self.n = n

    def __call__(self, x):
        return x * self.n

m = Multiplier(3)

print(m(10))  # 30

 

2. __len__()

__len__()은 객체의 길이를 정의하는 매직 메서드로, len(obj)를 호출할 때 자동으로 실행됩니다. 이 메서드를 구현하면 사용자 정의 객체도 리스트나 문자열처럼 길이를 가질 수 있으며, 내부 데이터의 개수를 반환하도록 작성하면 됩니다.

class Basket:
    def __init__(self):
        self.items = []

    def __len__(self):
        return len(self.items)

b = Basket()
b.items = ["사과", "바나나", "오렌지"]

print(len(b))  # 3

 

 

5. with 문

with 문은 파일, 네트워크, DB 연결처럼 사용 후 반드시 정리(clean-up)가 필요한 자원을 안전하게 관리하기 위한 문법으로, 블록이 시작될 때 필요한 작업을 수행하고 종료될 때 자동으로 정리 작업을 실행해줍니다. 이를 통해 try-finally를 직접 작성하지 않아도 되고, 예외가 발생하더라도 자원이 정상적으로 해제되도록 보장할 수 있습니다.

 

1. __enter__()

__enter__()는 with 문에 진입할 때 자동으로 호출되는 매직 메서드로, 자원을 준비하거나 초기화하는 역할을 합니다. 이 메서드에서 반환한 값은 as 뒤의 변수에 할당되어 with 블록 내부에서 사용됩니다. 

 

2. __exit__()

__exit__()는 with 블록이 끝날 때 자동으로 호출되는 매직 메서드로, 사용한 자원을 정리(clean-up)하는 역할을 합니다. 이 메서드는 예외 발생 여부와 관계없이 반드시 실행되며, 예외가 발생한 경우에는 예외 타입, 값, traceback 정보를 인자로 받아 처리할 수 있습니다.

 

class MyResource:
    def __enter__(self):
        print("자원 열기")
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print("자원 정리")

with MyResource() as res:
    print("자원 사용 중")

 

class MyResource:
    def __enter__(self):
        print("자원 열기")
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print("자원 정리")
        print("예외 타입:", exc_type)

with MyResource():
    print("작업 중")
    1 / 0  # 에러 발생

👉 에러가 나도 __exit__()는 반드시 실행됩니다.

반응형

'인공지능_2026 > 1. 파이썬' 카테고리의 다른 글

모듈  (1) 2026.04.30
예외 처리  (0) 2026.04.30
객체지향 프로그래밍 4대 패러다임  (0) 2026.04.28
객체지향 프로그래밍(OOP)  (0) 2026.04.27
사용자 정의 함수  (0) 2026.04.27

관련글 더보기