본문으로 건너뛰기

메서드

파이썬 목차클래스레슨 55 / 59

목차

클래스 안에 정의한 함수를 **메서드(method)**라고 부릅니다. 메서드는 첫 번째 매개변수 self로 메서드를 부른 객체 자신을 받아, 그 객체의 속성을 읽거나 바꿉니다.

__init__과 self에서 배운 __init__도 객체를 만들 때 자동으로 불리는 특별한 메서드입니다. 이제 스탬프를 하나씩 찍는 add(self)처럼 우리가 원할 때마다 **객체.메서드()**로 부르는 일반 메서드를 만들어 봅시다.

7단계 중 1단계. 10번 줄: card = StampCard('민지')로 owner가 '민지', stamps가 0인 StampCard 객체 ①을 만들고 전역 이름표 card에 붙입니다.

1메서드 정의하고 부르기

클래스 안에 def add(self):를 정의해 두면, card.add()를 부를 때마다 파이썬이 마침표 앞의 객체 card를 첫 번째 매개변수 self 자리로 넘겨 줍니다. 즉 card.add()는 StampCard.add(card)의 줄임말입니다.

class StampCard:
    def __init__(self, owner):
        self.owner = owner
        self.stamps = 0

    def add(self):
        self.stamps += 1


card = StampCard('민지')
card.add()
card.add()
print(card.stamps)
실행 결과
2
  • def add(self):: 정의할 때는 첫 번째 매개변수 self를 반드시 적습니다.
  • card.add(): 부를 때는 마침표 앞의 card가 자동으로 self에 들어가므로 괄호 안은 비워 둡니다.
  • self.stamps += 1: self가 가리키는 card 객체의 .stamps 값을 1 올립니다.

그렇다면 손님 두 명(a, b)의 카드에서 a.add()를 두 번, b.add()를 한 번 부르면 두 카드의 스탬프 수는 각각 몇 개가 될까요? 먼저 맞혀 보세요.

class StampCard:
    def __init__(self, owner):
        self.owner = owner
        self.stamps = 0

    def add(self):
        self.stamps += 1


a = StampCard('민지')
b = StampCard('준호')
a.add()
a.add()
b.add()
print(a.stamps, b.stamps)
실행 결과 보기
실행 결과
2 1

예상과 다르면 그곳이 배울 곳입니다. a.add()를 부를 때는 self가 a 객체를 가리키고, b.add()를 부를 때는 self가 b 객체를 가리킵니다. 그래서 각 메서드는 자기를 부른 객체의 .stamps만 올립니다.

2추가 인자를 받고 값을 돌려주는 메서드

메서드도 일반 함수처럼 self 뒤에 추가 매개변수를 받을 수 있고, return으로 계산한 값을 돌려줄 수 있습니다(규칙 5).

class StampCard:
    def __init__(self, owner):
        self.owner = owner
        self.stamps = 0

    def add_many(self, n):
        self.stamps += n

    def left(self):
        return 10 - self.stamps
card = StampCard('민지')
card.add_many(4)
print(card.stamps)
print(card.left())
실행 결과
4
6
  • card.add_many(4)를 부르면 self에는 card가, 두 번째 매개변수 n에는 4가 들어갑니다.
  • card.left()는 무료 음료 기준인 10개까지 남은 개수(10 - self.stamps)를 계산해 6을 돌려줍니다.

자주 틀리는 곳

1. 메서드 정의에서 self를 빼먹는다

틀린 생각: card.add()처럼 괄호 안에 아무것도 안 넘기니 def add():처럼 매개변수도 비워 두면 된다.

card.add()를 부르면 파이썬은 늘 card 객체를 첫 번째 인자로 넘깁니다. 정의에 self가 없으면 인자 개수가 맞지 않아 TypeError가 납니다.

class StampCard:
    def add():
        print('추가')


card = StampCard()
card.add()
실행 결과
Traceback (most recent call last):  File "main.py", line 7, in <module>    card.add()    ~~~~~~~~^^TypeError: StampCard.add() takes 0 positional arguments but 1 was given

0개를 받는데 1개가 넘어왔다는 메시지의 1개가 바로 파이썬이 자동으로 넘긴 card 객체(self)입니다.

맞는 규칙: 클래스 안에 만드는 메서드의 첫 번째 매개변수에는 늘 self를 적습니다.

2. 메서드를 부를 때 괄호 ()를 빼먹는다

틀린 생각: card.add라고만 적어도 메서드가 실행되어 스탬프가 올라간다.

속성(card.stamps)은 값을 읽을 때 괄호를 쓰지 않지만, 메서드(card.add())는 함수이므로 괄호 ()를 붙여야 실제로 호출됩니다(규칙 5).

class StampCard:
    def __init__(self):
        self.stamps = 0

    def add(self):
        self.stamps += 1


card = StampCard()
card.add
print(card.stamps)
실행 결과
0

10번 줄 card.add는 메서드를 부르지 않고 메서드 객체만 가리켰다가 지나갔기 때문에 card.stamps는 0 그대로입니다.

맞는 규칙: 메서드를 실행할 때는 인자가 없더라도 반드시 빈 괄호를 붙여 card.add()로 부릅니다.

3. 메서드 안에서 self. 없이 속성 이름을 쓴다

틀린 생각: 같은 클래스 안이니 add(self) 안에서 self.stamps 대신 stamps라고만 적어도 객체의 속성을 찾아 준다.

파이썬은 self.이 붙지 않은 이름을 객체의 속성이 아니라 그 함수 칸의 지역 변수나 전역 변수로 찾습니다(규칙 5).

맞는 규칙: 메서드 안에서 자기 객체의 다른 속성이나 메서드를 쓸 때는 늘 앞에 self.을 붙여 self.stamps처럼 적습니다.

확인 문제

1. 다음 코드를 실행하면 무엇이 출력될까요?

class Counter:
    def __init__(self):
        self.n = 10

    def down(self, step):
        self.n -= step


c = Counter()
c.down(3)
c.down(2)
print(c.n)
힌트

처음 c.n은 10이고, c.down(3)과 c.down(2)가 차례로 c.n에서 얼마를 빼는지 보세요.

정답
실행 결과
5

10에서 3을 빼 7이 되고, 다시 2를 빼 5가 출력됩니다.

2. 직사각형의 넓이(self.w * self.h)를 돌려주는 area 메서드를 완성하려 합니다. 빈칸 (가)와 (나)를 채우세요.

class Rect:
    def __init__(self, w, h):
        self.w = w
        self.h = h

    def area(__(가)__):
        return __(나)__ * self.h


r = Rect(4, 5)
print(r.area())
힌트

메서드의 첫 번째 매개변수 이름과, 메서드 안에서 자기 객체의 w 속성을 읽는 표현을 적습니다.

정답
  • (가): self
  • (나): self.w

def area(self):로 정의하고 return self.w * self.h⁠로 자기 객체의 속성을 읽어 계산합니다.

3. 아래 코드에서 p.heal()을 불렀는데 10번 줄에서 TypeError가 납니다. 5번 줄을 어떻게 고쳐야 할까요?

class Player:
    def __init__(self):
        self.hp = 50

    def heal():
        self.hp += 10


p = Player()
p.heal()
힌트

p.heal()을 부를 때 파이썬이 자동으로 첫 번째 인자로 넘기는 객체를 받을 매개변수가 5번 줄에 있는지 보세요.

정답

5번 줄의 괄호 안에 self를 넣어 def heal(self):로 고칩니다.

아래 코드에서 card.add()를 한 번 더 불러 스탬프가 3개가 되도록 해 보세요.

처음 펼 때 약 6MB를 받습니다.컴퓨터에서 해 보기

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

파이썬 목차로