파이썬 생성자(init) 쉽게 이해하기
지난번에 강아지 클래스 만들 때 set_info() 같은 메서드로 이름이랑 나이를 따로 넣었던 거 기억나세요? 클래스를 먼저 만들고, 그다음에 메서드를 한 번 더 호출해서 정보를 채워 넣는 방식이었잖아요.
d = Dog()
d.set_info("뽀삐", 3)
두 줄을 꼭 써야 하니까 살짝 답답하셨을 거예요. 저도 그랬거든요.
근데 사실 이걸 한 줄에 끝낼 수 있는 방법이 있어요. 바로 오늘 배울 생성자예요.
파이썬 생성자, 왜 필요할까요
생성자라는 단어부터 이미 어렵죠. 그냥 이렇게 생각하시면 돼요.
인스턴스가 태어나는 순간에 자동으로 실행되는 초기 세팅 코드.
회원가입을 떠올리시면 이해가 쉬워요. 사이트에 가입할 때 이름, 이메일, 나이를 한 번에 입력하잖아요. 가입 버튼을 누르면 그 정보로 내 계정이 만들어지고요. 가입 따로, 정보 입력 따로 안 하죠. 한 번에 끝납니다.
파이썬에서도 이걸 똑같이 할 수 있어요. 그게 __init__이라는 메서드예요.
python init이 하는 일
코드부터 보시죠.
class Dog:
def __init__(self, name): # 인스턴스가 만들어질 때 자동 실행
self.name = name # 받은 이름을 인스턴스에 저장
처음 보면 양쪽에 언더스코어가 두 개씩 붙어 있어서 좀 이상해 보이실 거예요. __init__ 이게 도대체 뭔가 싶죠. 그냥 파이썬이 약속해 둔 특별한 이름이라고 생각하시면 됩니다. 양쪽에 두 개씩 정확히 맞춰서 쓰셔야 해요. 한 개씩 쓰면 자동 호출이 안 돼요.
이제 인스턴스를 만들어 볼게요.
d = Dog("뽀삐") # 괄호 안 값이 __init__으로 들어감
print(d.name) # 뽀삐
Dog() 괄호 안에 "뽀삐"를 넣었더니 그게 그대로 인스턴스의 이름이 됐어요.
여기서 헷갈리시는 분 많은데, 우리가 __init__을 직접 부른 적이 한 번도 없거든요. 그냥 Dog("뽀삐")라고 썼을 뿐이에요. 클래스 이름에 괄호를 붙이는 행위 자체가 __init__ 호출이에요. 회원가입 버튼 한 번 누르면 가입 양식이 자동으로 처리되는 거랑 똑같아요.
self.name = name이 진짜 헷갈리는 이유
이 줄이 처음에 제일 어렵더라고요.
self.name = name
이름이 양쪽 다 똑같아서 "뭐가 뭐지?" 싶잖아요. 일부러 다르게 써보면 의미가 명확해져요.
def __init__(self, n):
self.name = n # 오른쪽 n: 잠깐 받은 값 / 왼쪽 self.name: 인스턴스에 영구 저장
오른쪽 n은 __init__이 잠깐 들고 있는 매개변수예요. 함수가 끝나면 사라지죠. 왼쪽 self.name은 이 인스턴스에 영구적으로 붙여둘 속성이고요. 받은 값을 인스턴스의 짐칸에 넣어두는 작업이라고 보시면 돼요.
관례상 같은 이름을 많이 쓰는데, 그래서 더 헷갈리는 거예요. 익숙해지면 자연스러워집니다.
파이썬 인스턴스 여러 개 만들어보기
매개변수를 여러 개 받게 해볼게요.
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f"{self.name}({self.age}살): 멍멍!")
d1 = Dog("뽀삐", 3)
d2 = Dog("초코", 5)
d3 = Dog("바둑이", 7)
d1.bark() # 뽀삐(3살): 멍멍!
d2.bark() # 초코(5살): 멍멍!
같은 Dog 클래스에서 만들었는데 셋 다 정보가 다르죠. 클래스가 붕어빵 틀이고, 인스턴스가 거기서 찍어낸 붕어빵이에요. 틀은 하나지만 안에 든 팥, 슈크림, 초코는 다를 수 있는 거고요.
기본값을 미리 정해두기
매번 모든 값을 넣기 귀찮을 때는 기본값을 줄 수 있어요.
class Dog:
def __init__(self, name="이름없음", age=0):
self.name = name
self.age = age
d1 = Dog() # 이름없음, 0
d2 = Dog("뽀삐") # 뽀삐, 0
d3 = Dog("초코", 5) # 초코, 5
인자를 안 넘겨도 기본값이 들어가서 에러가 안 나요. 이거 의외로 자주 씁니다.
python init에서 자주 만나는 에러
가장 흔한 게 이 에러예요.
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
d = Dog("뽀삐")
# TypeError: __init__() missing 1 required positional argument: 'age'
age를 안 넣어서 난 에러예요. "필수 인자가 하나 빠졌어요"라는 뜻이거든요. __init__에 적어둔 매개변수 개수만큼 모두 넣어주셔야 해요.
그리고 가끔 __init__에서 return으로 뭘 돌려주려고 하시는 분이 있는데, 그러면 안 돼요. 생성자는 초기 세팅만 하는 거지 값을 반환하는 게 아니거든요.
실용 예제: BankAccount 클래스 만들기
조금 실전스러운 예제로 마무리할게요.
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner # 예금주
self.balance = balance # 잔액 (기본 0원)
def deposit(self, amount):
self.balance += amount
print(f"{amount}원 입금. 잔액: {self.balance}원")
def withdraw(self, amount):
if amount > self.balance:
print("잔액 부족")
return
self.balance -= amount
print(f"{amount}원 출금. 잔액: {self.balance}원")
acc = BankAccount("홍길동", 10000)
acc.deposit(5000) # 5000원 입금. 잔액: 15000원
acc.withdraw(3000) # 3000원 출금. 잔액: 12000원
acc.withdraw(20000) # 잔액 부족
계좌를 만드는 그 순간에 예금주와 시작 잔액이 같이 세팅되죠. 한 번 만들어두면 그 계좌만의 잔액이 계속 따라다니고요.
여러분도 한번 해보세요. 위 코드에 transfer(other_account, amount) 메서드를 추가해서 한 계좌에서 다른 계좌로 돈을 옮기는 기능을 만들어 보시면 좋아요. 막히시면 댓글로 남겨주세요.
근데 막상 이렇게 만들다 보면 또 고민이 생겨요. 강아지 클래스 다음에 고양이 클래스, 햄스터 클래스도 만들어야 하면 어떨까요? 매번 이름이랑 나이 받는 코드를 똑같이 또 쓰는 건 좀 비효율적이잖아요.
공통된 부분을 한 번만 쓰고, 나머지를 가져다 쓰는 방법이 있는데요. 그게 다음에 다룰 상속이에요.
제 글이 도움이 되셨다면 댓글 & 공감 부탁드려요 😀
'Application > Python' 카테고리의 다른 글
| [Python] 파이썬 리스트 컴프리헨션, 코드 한 줄로 줄이는 마법 (0) | 2026.05.13 |
|---|---|
| [Python] 파이썬 상속과 오버라이딩, 클래스를 또 만들지 마세요 (1) | 2026.05.12 |
| [Python] 파이썬 클래스, 객체지향이란 무엇일까 (0) | 2026.05.08 |
| [Python] 파이썬 계산기 만들기 (첫 미니 프로젝트) (0) | 2026.05.07 |
| [Python] 파이썬 예외처리, try except로 오류 잡는 법 (0) | 2026.05.06 |