파이썬73번5 MIN
self 키워드 완전 이해
Python 메서드의 첫 번째 매개변수 self가 무엇인지, 어떻게 자동 전달되는지, 메서드 체이닝에 활용하는 방법을 설명합니다.
이 글은 PALDYN Tech Blog의 글입니다.원문 보기
지난 글에서 인스턴스 속성과 클래스 속성의 차이를 살펴보았습니다. 메서드를 정의할 때마다 등장하는 self는 Python 초심자에게 낯선 개념입니다. 이번 글에서는 self가 무엇인지, 왜 필요한지, 어떻게 동작하는지 원리부터 알아봅니다.
self는 무엇인가
self는 메서드가 호출될 때 파이썬이 자동으로 첫 번째 인수로 전달하는 현재 인스턴스입니다. 이름은 관례일 뿐 Python 키워드가 아니며, this나 다른 이름을 써도 동작합니다. 그러나 PEP 8은 self를 강력히 권장합니다.
class Dog:
def bark(self):
print(f"{self.name} says Woof!")
rex.bark()를 호출하면 파이썬은 내부적으로 Dog.bark(rex)와 동일하게 처리합니다. rex가 self 자리에 전달됩니다.
자동 전달 원리
Python의 메서드는 클래스 딕셔너리에 함수로 저장됩니다. 인스턴스를 통해 접근할 때 디스크립터 프로토콜이 개입해 인스턴스를 첫 번째 인수로 바인딩한 바운드 메서드(bound method)를 만들어 반환합니다.
class Dog:
def bark(self):
return "Woof"
rex = Dog()
print(rex.bark) # <bound method Dog.bark of <Dog object>>
print(Dog.bark) # <function Dog.bark at ...>
# 동일한 호출
rex.bark() # 바운드 메서드 호출
Dog.bark(rex) # 언바운드로 인스턴스 직접 전달
바운드 메서드를 변수에 저장해도 인스턴스 참조를 유지합니다.
fn = rex.bark # rex가 바인딩된 상태
print(fn()) # Woof — rex 없이 호출 가능
print(fn.__self__ is rex) # True
self를 통한 속성 접근
self를 통해 인스턴스 속성에 읽고 쓰거나, 같은 클래스의 다른 메서드를 호출합니다.
class Rectangle:
def __init__(self, w, h):
self.w = w
self.h = h
def area(self):
return self.w * self.h
def perimeter(self):
return 2 * (self.w + self.h)
def is_square(self):
return self.w == self.h # self 속성 비교
def scale(self, factor):
self.w *= factor # self 속성 수정
self.h *= factor
return self # self 반환 → 체이닝 가능
메서드 체이닝
메서드가 self를 반환하면 결과에 곧바로 다른 메서드를 연결할 수 있습니다. 이를 Fluent Interface 또는 메서드 체이닝이라 합니다.
r = Rectangle(4, 3)
print(r.scale(2).area()) # 48 — scale 후 area 연속 호출
클래스 메서드와 정적 메서드에서의 차이
@classmethod는 첫 인수로 클래스 자체(cls)를 받습니다. @staticmethod는 첫 번째 특수 인수가 없습니다.
class Dog:
count = 0
def __init__(self, name):
self.name = name
Dog.count += 1
@classmethod
def get_count(cls):
return cls.count # cls = Dog 클래스
@staticmethod
def validate_name(name):
return isinstance(name, str) and len(name) > 0
print(Dog.get_count()) # 0
Dog("Rex")
print(Dog.get_count()) # 1
print(Dog.validate_name("Rex")) # True
self(인스턴스), cls(클래스), 없음(정적) — 세 가지 종류의 메서드는 첫 번째 인수로 구분됩니다.
self를 빠뜨리는 실수
class Dog:
def bark(): # self 없음
return "Woof"
d = Dog()
d.bark() # TypeError: bark() takes 0 positional arguments but 1 was given
d.bark()를 호출할 때 파이썬은 d를 첫 번째 인수로 전달하려 하지만, bark는 인수를 받지 않으므로 에러가 발생합니다. 인스턴스 메서드는 항상 self를 첫 번째 매개변수로 선언해야 합니다.
self와 id 확인
self가 정말 같은 인스턴스를 가리키는지 확인할 수 있습니다.
class Dog:
def who_am_i(self):
return id(self)
rex = Dog()
print(id(rex)) # 예: 140234567890
print(rex.who_am_i()) # 동일한 값 — 같은 객체
지난 글: 인스턴스 속성 vs 클래스 속성
다음 글: init vs new
읽어주셔서 감사합니다. 😊

