객체를 생성한 뒤에 user1.name = "김파이", user1.point = 1500과 같이 일일이 수동으로 속성을 주입해주어야 했다는 점입니다. 이 방식은 코드가 길어질 뿐만 아니라, 개발자가 실수로 특정 속성을 입력하는 것을 빠뜨리면 객체가 제대로 완성되지 않은 채 프로그램이 돌아가다가 중간에 터지는 버그로 이어지게 됩니다.

저 역시 처음 클래스를 다룰 때 속성 초기화를 깜빡하고 넘어가서 AttributeError: 'Member' object has no attribute 'name' 에러를 수없이 만나며 곤욕을 치렀습니다. 오늘은 객체가 태어나는 그 순간 호출되어 필수 데이터들을 안전하게 차곡차곡 채워주는 생성자 메서드 __init__과 인스턴스 변수의 동작 원리를 정리해 드립니다.


1. 생성자(Constructor) __init__이란 무엇인가?

파이썬 클래스 내부를 들여다보면 언더바 2개가 앞뒤로 붙은 특수한 형태의 메서드를 자주 보게 됩니다. 이런 메서드들을 '매직 메서드(Magic Method)' 또는 '던더(Dunder - Double Underbar) 메서드'라고 부릅니다.

그중 대표격인 __init__은 개발자가 직접 명시적으로 호출하지 않아도, 클래스명()을 통해 객체가 생성되는 그 순간 파이썬 시스템에 의해 자동으로 가장 먼저 실행되는 생성자 메서드입니다.

  • __init__의 역할: 객체가 메모리에 할당될 때 전달받은 초기값들을 가지고 객체의 필수 속성을 안전하게 세팅(초기화)해 줍니다.


2. 생성자를 활용한 깔끔하고 안전한 객체 초기화

생성자를 사용하면 객체를 만드는 코드 한 줄 안에서 필수 데이터들을 전달할 수 있어 코드가 비약적으로 간결해집니다.

Python
class Member:
    # 객체가 생성될 때 자동으로 실행되는 생성자 메서드
    def __init__(self, name, email, point=0):
        # 인스턴스 변수 선언 및 초기화
        self.name = name
        self.email = email
        self.point = point
        print(f"[알림] {self.name} 회원 객체가 성공적으로 생성되었습니다.")

    def display_profile(self):
        print(f"회원명: {self.name} | 이메일: {self.email} | 포인트: {self.point}점")

이제 이 클래스를 활용해 객체를 생성해 보겠습니다.

Python
# 1. 객체 생성과 동시에 필수 값 전달
user1 = Member("김파이", "pie@python.com", 1500)
user2 = Member("이객체", "object@python.com")  # point는 기본값 0 적용

# 2. 프로필 출력 메서드 실행
user1.display_profile()
user2.display_profile()

2편처럼 객체를 만든 뒤 user1.name = ... 과 같이 지저분하게 코드를 여러 줄 적을 필요가 완전히 사라졌습니다. 또한 필수 매개변수인 name이나 email을 전달하지 않고 Member()를 호출하면 파이썬이 생성 단계에서 즉시 에러를 발생시켜 불완전한 객체가 생성되는 것을 구조적으로 막아줍니다.


3. 인스턴스 변수(Instance Variable)의 생명주기와 독립성

__init__ 메서드 내부에서 self.변수명 형태로 선언된 변수를 인스턴스 변수라고 부릅니다.

인스턴스 변수의 가장 큰 특징은 "각각의 객체(인스턴스)마다 완전히 독립된 메모리 공간을 소유한다"는 점입니다.

user1과 user2는 동일한 Member 클래스라는 설계도로부터 태어났지만, user1.point의 값을 5000으로 변경해도 user2.point에는 전혀 영향을 주지 않습니다. self가 각 객체 고유의 메모리 주소를 가리키고 있기 때문입니다.

객체가 생성될 때 메모리 뒤편에서 일어나는 일 3단계

  1. user1 = Member(...) 구문이 실행되면, 파이썬은 RAM 메모리의 빈 공간에 새로운 객체를 위한 자리를 틉니다.

  2. 파이썬 내부 특수 메서드인 __new__()가 작동해 알맹이가 비어있는 진짜 객체를 만든 뒤, 이 객체의 메모리 주소를 __init__의 첫 번째 인자인 self로 넘깁니다.

  3. __init__ 함수가 실행되면서 self.name, self.email 같은 인스턴스 변수들에 입력받은 값들이 연결되고, 초기화가 끝난 완성형 객체가 최종적으로 user1 변수에 할당됩니다.


4. 생성자 작성 시 초보자가 자주 범하는 실수 2가지

1) __init__ 메서드에서 값을 반환(return)하려고 할 때

생성자는 객체를 초기화하는 것이 목적이므로 반환값은 무조건 None이어야 합니다. 만약 __init__ 내부에서 return "성공" 또는 return 100과 같이 특정 값을 반환하려고 시도하면 TypeError: __init__() should return None 에러가 발생하며 프로그램이 다운됩니다.

2) self.을 빼먹고 일반 변수로 선언하는 경우

__init__ 내부에서 name = name_param 처럼 앞에 self.을 붙이지 않으면, 해당 변수는 객체의 속성이 아니라 __init__ 함수 내부에서만 잠깐 살다 사라지는 지역 변수(Local Variable)가 되어버립니다. 함수 실행이 끝나면 그대로 증발하므로 추후 user1.name 형태로 접근할 수 없게 되니 주의해야 합니다.


핵심요약

  • __init__은 객체가 생성될 때 자동으로 실행되는 생성자 메서드로, 객체에 필수적인 인스턴스 변수들을 안전하게 초기화합니다.

  • 인스턴스 변수(self.변수명)는 각 객체가 독립적으로 소유하는 고유 데이터 공간이므로 객체 간 데이터 간섭이 발생하지 않습니다.

  • 생성자 내부에서는 return으로 특정 값을 반환해서는 안 되며, 변수 선언 시 반드시 앞에 self.을 붙여야 인스턴스 속성으로 유지됩니다.