객체를 생성한 뒤에 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. 생성자를 활용한 깔끔하고 안전한 객체 초기화
생성자를 사용하면 객체를 만드는 코드 한 줄 안에서 필수 데이터들을 전달할 수 있어 코드가 비약적으로 간결해집니다.
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}점")
이제 이 클래스를 활용해 객체를 생성해 보겠습니다.
# 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단계
user1 = Member(...)구문이 실행되면, 파이썬은 RAM 메모리의 빈 공간에 새로운 객체를 위한 자리를 틉니다.파이썬 내부 특수 메서드인
__new__()가 작동해 알맹이가 비어있는 진짜 객체를 만든 뒤, 이 객체의 메모리 주소를__init__의 첫 번째 인자인self로 넘깁니다.__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.을 붙여야 인스턴스 속성으로 유지됩니다.


0 댓글