본문 바로가기
Python/기초

[파이썬/Python] Class의 정의와 사용법(feat. 함수와의 차이)

by 모두의 케빈 2023. 7. 11.

Class의 정의


Class와 객체(Object), 그리고 인스턴스(Instance)

 

BTS, 마마무, 블랙 핑크, 싸이, 노을 .. 이들의 공통점은 무엇일까요? 그들은 모두 '가수'입니다. 가수라는 큰 틀 안에서 그룹이나 개인의 속성에 따라 BTS가 되기도 하고, 블랙 핑크가 되기도 합니다.

파이썬에서 Class란 이 '가수'와 같습니다. 상위 개념이자 큰 틀이고, 설계도라고도 합니다. Class에서 만들어지는 실체를 객체(Object)라고 합니다. 가수로부터 파생된 BTS, 마마무, 블랙 핑크와 같은 실존 가수들이 객체에 해당합니다.

인스턴스(Instance)는 관계를 표현할 때 주로 사용합니다. Class와 객체의 관계를 표현할 때, "BTS는 가수의 인스턴스(Instance)다."라고 표현합니다.

정리하면 객체와 인스턴스는 동일한 개념이며 관계를 표현할 때는 인스턴스, 실체를 명명할 때는 객체라고 부릅니다.

BTS, 마마무, 블랙 핑크, 싸이, 노을은 모두 가수의 Instance 들이야. (관계를 표현)
BTS, 마마무, 블랙 핑크, 싸이, 노을은 모두 객체야. (실체를 명명)

 

 

Class는 왜 필요할까?

 

Class는 하나의 큰 틀이자 설계도입니다. 프로그래머는 자신의 생각이나 세상에 존재하는 개념을 Class로 구현합니다. Class가 이미 정의되어 있다면, 프로그래머들은 자신에게 필요한 Class를 쉽게 재사용할 수 있다는 장점이 있습니다.

그럼 함수와 Class는 어떤 점이 다를까요? 두 개념 모두 코드의 재사용성을 높여준다는 장점이 있습니다. 함수와 Class의 차이점은 상태를 관리하는 측면에서 두드러집니다.

Class로 객체를 선언하면, 각 객체는 독립적입니다. 하나의 객체의 상태를 변경해도 다른 객체에는 영향을 미치지 않기 때문에 Class는 상태를 관리하기 용이합니다.

반면 함수는 여러 상태를 동시에 관리할 수 없습니다. 정확히 말하면 관리하려는 상태의 개수만큼 변수와 함수를 새롭게 재정의해야 합니다.

예시를 들어볼까요. 가수(Singer)의 앨범을 관리하는 함수를 만들었습니다. BTS 그룹의 누적되는 앨범을 관리하기 위한 전역 변수 albums와 함수 singer를 선언했습니다. 시간이 지나며 늘어나는 앨범을 표현하기 위해 함수를 여러 번 호출해 보겠습니다.

albums = ''

def singer(name, album):
    global albums
    albums += ' ' + album
    return albums
    
bts = singer(BTS, '1집')
print(bts)
bts = singer(BTS, '2집')
print(bts)
bts = singer(BTS, '3집')
print(bts)

# 위 코드의 결과값
1집
1집 2집
1집 2집 3집

 

자 그럼, 마마무를 비롯한 다른 가수들의 앨범은 어떻게 관리해야 할까요? 새로운 전역 변수와 새로운 함수를 선언해줘야 합니다. 왜냐면, BTS의 앨범을 관리하는 전역 변수와 함수를 그대로 사용하면 BTS의 상태가 바뀔 때마다 마마무라는 그룹의 상태도 같이 바뀌기 때문입니다. (함수는 독립적이지 못함)

albums_of_mamamu = ''

def singer_mamamu(name, album):
    global albums_of_mamamu
    albums_of_mamamu += ' ' + album
    return albums_of_mamamu
    
mamamu = singer_mamamu('MAMAMU', '1집')
print(mamamu)
mamamu = singer_mamamu('MAMAMU', '2집')
print(mamamu)
mamamu = singer_mamamu('MAMAMU', '3집')
print(mamamu)

# 위 코드의 결과값
1집
1집 2집
1집 2집 3집

 

Class는 이러한 함수의 불편함(여러 상태를 표현하기 위해 그 개수만큼 함수와 변수를 재정의해야 하는)을 해결할 수 있습니다. 위의 함수와 동일한 기능을 수행하는 Class를 album_of_singer이라는 이름으로 구현했습니다.

그리고 이 Class로부터 bts와 mamamu라는 객체를 만들었습니다. 두 객체는 서로 독립이기 때문에, bts의 상태가 변해도 mamamu의 상태는 동일합니다. 따라서 여러 객체의 상태를 관리하기 위해 class를 여러 번 선언할 필요가 없습니다. 

class album_of_singer():
    def __init__(self,name):
        self.name = name
        self.albums = ''
        
    def add_album(self,album):
        self.albums += ' ' + album
        return self.albums
    
    
bts = album_of_singer('BTS')
bts.add_album('1집')
bts.add_album('2집')
print("{}그룹의 앨범들: {}".format(bts.name, bts.albums))

mamamu = album_of_singer('MAMAMU')
mamamu.add_album('1집')
mamamu.add_album('2집')
mamamu.add_album('3집')
print("{}그룹의 앨범들: {}".format(mamamu.name, mamamu.albums))

# 위 코드의 결과값
BTS그룹의 앨범들:  1집 2집
MAMAMU그룹의 앨범들:  1집 2집 3집

 

 

Class의 구성 요소와 사용법


Class의 구성 요소(속성, 메서드)와 정의하는 방법

 

Class는 속성과 메서드로 구성되어 있습니다. Class 안에서 사용되는 변수를 속성(Attribute)이라고 합니다. 속성은 Class 안으로 들어온 값을 저장하고 상태를 관리합니다.

Class 안에서 사용되는 함수를 메서드(Method)라고 합니다. Class 안에서 사용되는 모든 메서드는 첫 번째 인자로 자기 자신을 받습니다. 그래서 관례적으로 'self'라는 변수를 첫 번째 인자의 자리에 사용합니다. (자기 자신을 계속 인자로 주기 때문에 상태를 관리할 수 있는 겁니다.)

'def __init__'은 Class 안에서 사용되는 함수, 즉 메서드입니다. init은 Initialize의 약자로 Class를 선언하면서 가장 먼저 실행되는 메서드입니다. init은 print()처럼 파이썬에서 사용하는 예약어입니다. Class를 토대로 객체를 만들 때, 몇 개의 인자가 필요한지는 __init__ 메서드에서 정의한 인자의 개수와 동일합니다.

Class는 아래와 같이 정의합니다. class라는 예약어 뒤에 사용자가 지정하는 class명을 적고 소괄호()와 세미콜론(:)을 입력합니다. 그리고 __init__ 메서드까지는 기본적으로 선언해 줍니다. (선언하지 않는 경우도 있지만 그런 경우는 굳이 class를 사용하지 않아도 되는 경우가 대부분임)

class 사용자가 지정하는 이름():
    def __init__(self, 속성들):
        pass

 

 

Class안의 메서드와 속성은 어떻게 접근하나요?

 

위의 정의를 토대로 과일 바구니 Class를 만들어 보겠습니다. 과일 바구니 안에는 과일들의 리스트가 속성으로 있습니다. 그리고 과일을 추가하거나 뺄 수 있는 메서드가 있습니다.

class Fruit_basket():
    def __init__(self,fruit_list):
        self.fruit_list = fruit_list
        
    def add_fruit(self, fruit):
        self.fruit_list.append(fruit)
        print("{}을 추가했습니다.".format(fruit))
        
    def sub_fruit(self, fruit):
        self.fruit_list.remove(fruit)
        print("{}을 제거했습니다.".format(fruit))

 

Class의 메서드와 속성을 사용하기 위해서는 먼저 객체를 선언해야 합니다. 객체는 'Class명(인자)'로 선언합니다.

fruits = Fruit_basket(['사과','오렌지','바나나'])

 

선언한 객체의 속성에 접근하기 위해서는 객체에 마침표(.)를 찍고 접근하고자 하는 객체의 속성 이름을 입력하면 됩니다.

print(fruits.fruit_list)

# 위 코드의 결과값
['사과', '오렌지', '바나나']

 

객체의 메서드도 마찬가지로 마침표(.)로 접근합니다. 접근하고자 하는 메서드의 이름과 필요한 인자를 입력하면 객체 내 메서드를 사용할 수 있습니다.

fruits.add_fruit('용과')
fruits.add_fruit('수박')
fruits.sub_fruit('바나나')

print(fruits.fruit_list)

# 위 코드의 결과값
용과을 추가했습니다.
수박을 추가했습니다.
바나나을 제거했습니다.
['사과', '오렌지', '용과', '수박']

 

 

댓글