본문으로 건너뛰기

클래스와 객체

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

목차

같은 모양의 값을 여러 개 다루고 싶을 때 **class로 나만의 자료형(틀)**을 만듭니다. 클래스 이름 뒤에 괄호를 붙여 **클래스이름()**을 부를 때마다 그 틀로 찍어 낸 **새 객체(값)**가 하나씩 만들어지고, 각 객체는 자기만의 속성(객체.이름) 칸을 따로 가집니다.

리스트 안의 딕셔너리에서는 손님마다 스탬프 카드를 {'owner': '민지', 'stamps': 3}⁠처럼 딕셔너리로 표현했습니다. 하지만 딕셔너리는 키 이름을 'stamp'라고 잘못 적어도 만들 때는 모르고 지나치기 쉽습니다. 이번 단원에서는 스탬프 카드라는 **클래스(틀)**를 정의하고, 그 틀로 손님마다 객체를 만들어 다루는 법을 배웁니다. 이 단원(클래스)을 이미 안다면 단원 연습 문제부터 풀고 틀린 레슨만 보세요.

8단계 중 1단계. 클래스 틀 StampCard로 객체 두 개를 따로 만들고 각 객체에 속성을 붙입니다.

1클래스 정의하기와 객체 만들기

클래스는 class 클래스이름:으로 정의합니다. 클래스 이름은 보통 단어 첫 글자를 대문자(StampCard)로 적습니다. 아직 안에 넣을 동작이 없을 때는 빈 블록임을 뜻하는 pass를 적어 둡니다.

class StampCard:
    pass


a = StampCard()
b = StampCard()
a.stamps = 3
b.stamps = 0
print(a.stamps, b.stamps)
실행 결과
3 0
  • class StampCard:: 스탬프 카드를 찍어 내는 **틀(클래스)**만 만듭니다. 아직 실제 카드는 하나도 없습니다.
  • a = StampCard()와 b = StampCard(): 함수를 부르듯 뒤에 괄호 ()를 붙여 부를 때마다 서로 다른 새 객체가 하나씩 만들어져 a와 b에 각각 붙습니다(규칙 3).
  • a.stamps = 3: 객체 뒤에 마침표(.)를 찍고 이름을 적으면 그 객체 안에 **속성(attribute)**이 생깁니다. a와 b는 별개의 객체이므로 a.stamps를 바꿔도 b.stamps는 바뀌지 않습니다.

2같은 객체를 가리키는 두 이름과 새 객체 만들기

리스트에서 배운 이름표 규칙(규칙 3)은 객체에도 똑같이 적용됩니다. 아래 코드에서 c = a를 실행한 뒤 c.stamps = 9로 바꾸면 a.stamps와 b.stamps는 각각 무엇이 찍힐지 먼저 맞혀 보세요.

class StampCard:
    pass


a = StampCard()
b = StampCard()
a.stamps = 3
b.stamps = 0
c = a
c.stamps = 9
print(a.stamps, b.stamps)
실행 결과 보기
실행 결과
9 0

예상과 다르면 그곳이 배울 곳입니다. b = StampCard()는 괄호 ()를 붙여 새 객체 ②를 만들었지만, c = a는 새 객체를 만들지 않고 a가 가리키던 객체 ①에 이름 c를 하나 더 붙였습니다(규칙 3). 그래서 c.stamps = 9는 객체 ①의 칸을 바꾸어 a.stamps도 9로 보이고, 별개의 객체 ②를 가리키는 b.stamps는 0 그대로입니다.

코드 꼴하는 일
b = StampCard()StampCard 틀로 새 객체를 만들어 b를 붙임
c = a새 객체를 만들지 않고 a가 가리키는 같은 객체에 c를 붙임

예제

손님 두 명의 스탬프 카드에 주인 이름과 개수 적기

객체 하나에 여러 속성(.owner, .stamps)을 붙이고 읽는 예제입니다.

class StampCard:
    pass


c1 = StampCard()
c1.owner = '민지'
c1.stamps = 8

c2 = StampCard()
c2.owner = '준호'
c2.stamps = 2

print(c1.owner, c1.stamps)
print(c2.owner, c2.stamps)
실행 결과
민지 8
준호 2

c1 객체와 c2 객체는 각자 자기만의 .owner 칸과 .stamps 칸을 따로 가지고 있습니다.

자주 틀리는 곳

1. 객체를 만들 때 괄호 ()를 빠뜨린다

틀린 생각: card = StampCard라고만 적어도 새 스탬프 카드 객체가 만들어진다.

괄호 없이 card = StampCard라고 적으면 새 객체를 찍어 내지 않고 클래스(틀) 자체에 이름 card를 하나 더 붙입니다.

class StampCard:
    pass


a = StampCard
b = StampCard
a.stamps = 3
b.stamps = 0
print(a.stamps)
실행 결과
0

a와 b가 모두 새 객체가 아니라 같은 StampCard 클래스 틀을 가리키게 되어, b.stamps = 0이 a.stamps까지 덮어써 버렸습니다.

맞는 규칙: 클래스로 새 객체를 만들 때는 반드시 뒤에 괄호를 붙여 StampCard()로 부릅니다.

2. 아직 만들지 않은 속성을 읽으려 한다

틀린 생각: StampCard()로 객체를 만들면 .stamps 같은 속성이 기본값 0으로 저절로 들어 있다.

빈 클래스 StampCard로 만든 객체에는 처음에 아무 속성도 들어 있지 않습니다. 속성에 값을 붙여 주기 전에 읽으려 하면 AttributeError가 납니다.

class StampCard:
    pass


card = StampCard()
print(card.stamps)
실행 결과
Traceback (most recent call last):  File "main.py", line 6, in <module>    print(card.stamps)          ^^^^^^^^^^^AttributeError: 'StampCard' object has no attribute 'stamps'

StampCard 객체에 'stamps'라는 속성이 없다는 뜻입니다. 객체를 만들자마자 처음 속성이 자동으로 채워지게 하는 법(__init__)은 바로 다음 레슨에서 배웁니다.

맞는 규칙: 속성을 읽기 전에 먼저 card.stamps = 0처럼 값을 붙여 주거나, 다음 레슨에서 배울 __init__으로 처음 값을 넣어 둡니다.

3. 한 객체의 속성을 바꾸면 다른 객체도 바뀐다고 생각한다

틀린 생각: a와 b가 둘 다 StampCard()로 만든 객체이니 a.stamps를 올리면 b.stamps도 함께 오른다.

StampCard()를 부를 때마다 매번 독립된 새 객체가 만들어집니다.

맞는 규칙: StampCard()로 각각 만든 객체는 서로 남남이므로 한 객체의 속성을 바꿔도 다른 객체는 바뀌지 않습니다(규칙 3).

확인 문제

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

class Cup:
    pass


x = Cup()
y = Cup()
x.size = 'L'
y.size = 'M'
x.size = 'S'
print(x.size, y.size)
힌트

x = Cup()과 y = Cup()이 같은 객체인지 서로 다른 두 객체인지 보고, x.size = 'S'가 어느 객체의 속성을 바꾸는지 보세요.

정답
실행 결과
S M

x와 y는 서로 다른 두 Cup 객체를 가리킵니다. x.size = 'S'는 x가 가리키는 객체의 size만 'S'로 바꾸므로 S M이 출력됩니다.

2. Book 클래스로 새 객체를 만들어 변수 b에 붙이려고 합니다. 빈칸을 채우세요.

class Book:
    pass


b = ________
b.title = '파이썬'
print(b.title)
힌트

클래스 이름 뒤에 무엇을 붙여야 새 객체가 만들어지는지 떠올려 보세요.

정답

Book()입니다 (b = Book()). 괄호 ()를 붙여야 새 객체가 만들어집니다.

3. 서로 다른 두 상자 객체를 만들어 크기를 따로 저장하려는데 두 상자 모두 20이 찍혔습니다. 5~6번 줄을 어떻게 고쳐야 10 20이 찍힐까요?

class Box:
    pass


b1 = Box
b2 = Box
b1.w = 10
b2.w = 20
print(b1.w, b2.w)
힌트

5~6번 줄에서 Box 뒤에 괄호가 있는지 확인해 보세요.

정답

5~6번 줄에 괄호를 붙여 b1 = Box()와 b2 = Box()로 고칩니다.

class Box:
    pass


b1 = Box()
b2 = Box()
b1.w = 10
b2.w = 20
print(b1.w, b2.w)
실행 결과
10 20

괄호를 붙이지 않으면 새 객체가 만들어지지 않고 두 변수가 같은 Box 클래스를 가리킵니다.

아래 코드에서 a = StampCard()와 b = StampCard()의 괄호 ()를 빼 보면 출력이 어떻게 달라지는지 확인해 보세요.

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

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

파이썬 목차로