2.21. 메서드와 속성¶
메서드 는 클래스 안에 정의된 함수입니다. 첫 번째 매개변수는 메서드가 호출된 인스턴스이며, 관례상 self 로 이름 짓습니다.
2.21.1. 인스턴스 메서드¶
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def magnitude(self):
return (self.x ** 2 + self.y ** 2) ** 0.5
p = Point(3, 4)
print(p.magnitude())
출력:
5.0
호출 p.magnitude() 는 p 를 self 로 자동으로 전달합니다. 메서드 본문은 함수가 매개변수를 통해 이름을 읽고 갱신하는 것과 같은 방식으로 self 를 통해 속성을 읽고 갱신합니다.
2.21.2. 인스턴스 속성 대 클래스 속성¶
self 에 할당된 속성 – 일반적으로 __init__ 안에서 – 은 그 하나의 인스턴스에 속합니다:
a = Point(1, 2)
b = Point(10, 20)
a.x = 99
print(a.x, b.x) # 99 10
a.x 와 b.x 는 서로 다른 저장 공간입니다. 하나를 변경해도 다른 하나에 영향을 주지 않습니다.
메서드 바깥 의 클래스 본문에서 할당된 이름은 클래스의 모든 인스턴스가 공유합니다:
class Counter:
kind = "tally" # class attribute -- shared
def __init__(self):
self.value = 0 # instance attribute -- per instance
a = Counter()
b = Counter()
print(a.kind, b.kind) # tally tally
클래스 속성은 클래스 자체에 존재하며 공유됩니다. 인스턴스 속성은 각 인스턴스에 존재합니다.¶
클래스 속성은 인스턴스 속성과 같은 방식으로 접근합니다(a.kind). Python은 먼저 인스턴스에서 찾고, 그다음 클래스에서 찾습니다. a.kind 에 할당하면 클래스 속성을 가리는 새 인스턴스 속성이 생성되고, b.kind 는 그대로 남습니다.
모든 인스턴스가 동일하게 봐야 하는 상수와 기본값에는 클래스 속성을 사용하세요. 각 객체가 자신만의 복사본을 소유해야 하는 상태에는 인스턴스 속성을 사용하세요.
2.21.3. __str__과 __repr__¶
두 개의 특수 메서드가 인스턴스가 어떻게 출력되는지를 제어합니다. __str__ 은 print() 가 사용하는 “친근한” 문자열을 반환하고, __repr__ 은 REPL과 컨테이너 표시 내부에서 사용되는 “개발자용” 문자열을 반환합니다:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return "(" + str(self.x) + ", " + str(self.y) + ")"
def __repr__(self):
return "Point(" + str(self.x) + ", " + str(self.y) + ")"
p = Point(3, 4)
print(p) # uses __str__
print([p, p]) # uses __repr__ inside the list
출력:
(3, 4)
[Point(3, 4), Point(3, 4)]
__repr__ 만 정의되어 있으면 print() 는 그것으로 대체합니다 – 그래서 잘 작성된 단일 __repr__ 하나면 보통 충분합니다. 친근한 형태가 개발자용 형태와 다르게 보여야 할 때만 __str__ 도 정의하세요. 객체를 다시 생성할 호출처럼 보이는 __repr__ 을 목표로 하세요. 출력된 값이 명확하면 디버깅이 극적으로 쉬워집니다.