IT is Smart
4.4 파이썬 재사용할 수 있는 프로그램 만들기-클래스(Class) 본문
1. 파이썬 소개, Introduction to Python
2. 파이썬의 특징, Features of Python (1/2)
2. 파이썬의 특징, Features of Python (2/2)
3.1 파이썬 버전 선택하기, Select Python version
3.2 OS Bit 버전 선택하기, Select OS Bit
3.3 설치파일 형태 선택하기, Select Setup File
4.1 파이썬 Interactive Shell 사용하기 (1/3)
4.1 파이썬 Interactive Shell 사용하기 (2/3)
4.1 파이썬 Interactive Shell 사용하기 (3/3)
4.2 파이썬 File Editor 사용하기-입력값 출력하기
4.2 파이썬 File Editor 사용하기-str(), int(), float() 함수 사용하기
4.3 파이썬 프로그램 만들어보기-continue & break문
4.3 파이썬 프로그램 만들어보기-try~except/finally문
4.4 파이썬 재사용할 수 있는 프로그램 만들기-함수(Function)
클래스에 대해 이야기하기 전에 잠시 게임 이야기를 하겠습니다.
딸아이와 함께 즐기는 PC게임이 있습니다. 메이플스토리2라는 게임인데요. 자신만의 캐릭터를 만들어 게임 속 여러 곳을 여행하면서 캐릭터를 성장시키는 롤플레잉(Role-playing) 게임입니다.
게임을 처음 시작하면 제일 먼저 자신이 플레이할 캐릭터를 만들어야 하는데, 나이트, 위자드, 레인저, 시프, 룬 블레이더, 소울 바인더, 버서커, 프리스트, 헤비거너, 어쎄신, 스트라이커, 이렇게 11개의 직업 중에서 하나를 선택해야 합니다.
직업을 선택한다는 것은 그 직업에서 사용할 수 있는 무기와 공격 스킬, 방어 스킬 등이 정해진다는 것입니다. 나이트는 검술을 사용하게 되고, 위자드는 마법을 사용하게 되는 거죠.
직업을 선택하고 나면 내 캐릭터의 스타일을 꾸밉니다. 성별 뿐만 아니고 헤어 스타일에서 피부색, 옷 등 내가 맘에 드는 대로 선택할 수 있습니다. 캐릭터는 게임 속에서 다른 게임 유저들과 완전히 구별되는 가상 세계 속의 또다른 나’이죠.
캐릭터 만들기의 완성은 캐릭터의 이름을 정하는 것입니다. 캐릭터 이름은 다른 게임 유저가 만든 적이 없는 완전히 새로운 이름을 정해 줘야 합니다. 그래야지 게임 속에서도 캐릭터의 이름으로 다른 유저들의 캐릭터와 나의 캐릭터를 구분할 수 있겠죠?
만약 다른 누군가가 이미 사용하고 있는 이름을 지정하려고 하면 ‘이미 사용중인 이름입니다’라는 메시지가 표시되면서 다른 이름을 만들게 합니다.
여기서는 ‘인스턴스1’이라고 이름을 지어주었는데 다행히 아무도 이 이름을 사용하지 않았네요. 정상적으로 캐릭터 만들기가 끝났습니다. 이렇게 캐릭터의 이름까지 정해주고 나면 새로운 캐릭터가 만들어집니다.
캐릭터가 완성이 되면 이제 게임을 즐길 수가 있습니다. 게임 속을 뛰어다니는 것은 ‘나이트’라는 직업이 아니고, ‘나이트’를 직업으로 하고 ‘인스턴스1’이라는 이름을 가진 캐릭터인 것입니다.
게임 이야기를 먼저 꺼낸 이유는 클래스를 좀더 쉽게 설명하기 위해서 입니다.
클래스는 앞에서 이야기한 게임 속 직업같은 것입니다. 그리고, 게임 속 캐릭터를 프로그래밍에서는 클래스의 인스턴스라고 부릅니다. 다른 설명으로는 클래스를 ‘설계도’에 비유하고 인스턴스는 ‘실체’ 또는 ‘객체’라고 말하기도 합니다.
클래스와 인스턴스의 관계를 다시 간략히 정리하면 다음의 그림과 같습니다.
클래스는 특성을 의미하는 변수와 행위를 의미하는 메서드(클래스 내부의 함수를 말합니다)로 구성이 됩니다. 인스턴스를 생성하는 단계를 거치면서 실제로 행위를 하는 객체가 만들어지고 객체는 각 특성의 실제 값을 가지고 메서드를 실행할 수 있습니다.
클래스의 구조는 다음과 같습니다.
class {클래스이름}:
{변수} 또는 {함수}
이제 실제 클래스를 만들어서 사용하는 예제를 살펴보겠습니다.
▷ 소스파일 URL : https://github.com/wonbird/Short-Term-Python-for-Beginners/blob/master/stp4b_13_define_class.py
이 코드에서는 4개의 클래스를 정의했습니다. 2라인의 Hero, 21라인의 Knight, 30라인의 Wizard, 그리고 42라인의 Dark가 그것입니다. 그런데 클래스를 선언한 방식을 보면 Hero클래스를 선언한 방식과 Knight, Wizard와 Dark를 선언한 방식이 다릅니다. Hero는 그냥 Hero인데, Knight는 Knight(Hero)이고 Wizard는 Wizard(Hero), Dark는 Dark(Hero)이죠.
이것을 클래스의 상속이라고 합니다. 부모 클래스의 변수와 메서드를 그대로 물려받기 때문에 복제와 다름 없는 수준입니다.
부모 클래스인 Hero는 1개의 변수와 4개의 메서드로 정의를 했습니다.
메서드 중에는 __init__()이라는 이름의 메서드 함수가 있는데 이는 파이썬에서 특별히 약속되어 있는 메서드들 중 하나로 초기화 메서드입니다. 밑줄을 2개씩 총4개 써야 합니다. 이 메서드는 클래스의 인스턴스가 만들어지는 순간에 자동으로 실행되기 때문에 인스턴스가 생성될 때 처리하고 싶은 것들을 정의하면 됩니다. 여기서는 사용하지 않았지만 인스턴스가 종료될 때 처리해야 할 작업이 있다면 __del__메서드를 정의하면 됩니다. __init__와 반대로 인스턴스가 없어질 때 호출되는 소멸 메서드이기 때문입니다. 나머지 3개의 메서드는 level_up(), say_hello(), attack()이라는 이름을 저 마음대로 정한 것입니다.
3라인은 인스턴스의 레벨 정보를 저장하기 위한 용도로 level이라는 변수를 만들고 1을 초기값으로 정했습니다.
5라인은 초기화 메서드__init__()을 정의했는데, self, name, gender라는 3개의 인수를 가지고 있습니다.
여기서 self는 모든 메서드의 첫번째 인수로 추가해줘야 하는 파이썬에서 특별히 정해진 인수입니다. 클래스의 인스턴스를 생성한 후에 인스턴스의 메서드를 실행시킬 때 첫번째 인수에 자기 자신을 넘겨줌으로써 자신의 메서드를 실행하라는 것을 인식하게 되는 것이죠.
좀더 쉽게 설명을 하면 26라인에서 def attack(self): 라고 Knight클래스의 메서드를 정의했습니다. 그리고 47라인에서 Knight클래스의 인스턴스 knight_tom을 생성한 후, 53라인에서 attack메서드를 실행합니다.
이 때 위의 설명대로 라면 53라인은 당연히 knight_tom.attack(knight_tom)이라고 작성되어야 합니다.
하지만 실제로는 knight_tom.attack()이라고 썼습니다. 자기 자신인 knight_tom을 인수로 넘겨주는 것을 생략한 것입니다. 클래스를 정의할 때는 self를 명시적으로 추가하도록 하고 인스턴스에서 실행할 때는 생략하도록 한 거죠. 이 부분이 파이썬의 특징이니 실수하지 않도록 합시다.
5라인에서 추가한 name과 gender 이 2개의 인수는 6라인과 7라인에서 인스턴스 변수인 self.name과 self.gender에 값을 넘겨 줍니다. 3라인의 level은 클래스 변수로 같은 클래스에서 생성된 객체 모두에게 공유되는 변수인데, 인스턴스 변수는 생성되는 객체 각각 고유한 값을 갖습니다.
9라인의 level_up메서드와 13라인의 say_hello메서드 그리고 17라인의 attack메서드는 모두 self인자만 가지고 다른 인자는 없습니다.
11라인에서 self.level을 호출하면서 str()함수를 사용했습니다.
3라인에서 봤듯이 level = 1이라고 초기값을 지정해주므로써 level변수는 정수형 값을 가지는 변수가 된 것입니다. 그래서 다른 문자열과 연결하기 위해서 숫자형 값을 문자형으로 변환해주는 str()함수를 사용한 것입니다.
14라인에서는 self.__class__.__name__이라는 꽤 생소한 형태의 변수를 호출했습니다.
소스코드 어디에서도 선언한 적이 없는 변수이지만 프로그램은 에러없이 정상적으로 실행됩니다. 눈치 빠른 분들은 이미 눈치채셨겠지만 __init__메서드에서 확인한 것과 같습니다. 변수명의 앞뒤로 __와 같이 밑줄을 2개씩 붙인 변수는 파이썬에서 이미 정해둔 내장 변수입니다. __class__변수는 인스턴스가 아닌 클래스를 가리키는 변수입니다. 그리고 __name__은 말 그대로 해당 모듈의 이름 정보를 가지고 있는 속성변수입니다. 따라서 self.__class__.__name__은 현재 실행되고 있는 인스턴스의 클래스 이름을 의미하는 것입니다.
18라인에서는 pass라는 키워드를 사용했습니다. 파이썬에서는 함수나 반복문을 정의할 때 반드시 1개 이상의 명령문을 포함해야 합니다. 하지만 프로그래밍을 하다 보면 아무것도 하지 않도록 정의해야 하는 경우도 있습니다. 이런 경우에 pass를 사용하면 됩니다.
2라인에서 와 같이 class 클래스명:은 일반적으로 클래스를 선언하는 방법입니다.
하지만 21라인, 30라인과 42라인을 보면 class 자식클래스명(부모클래스명):와 같은 형태로 선언되었습니다. 앞에서 말한 것처럼 이렇게 선언하는 것을 클래스의 상속이라고 합니다.
class 키워드 다음에 나오는 클래스가 자식 클래스이고, 괄호 안에 나오는 클래스가 부모 클래스입니다.
자식 클래스는 별도로 정의하지 않더라도 부모 클래스에서 정의된 속성과 메서드를 그대로 물려받아서 사용할 수 있습니다. 42라인의 Dark클래스의 경우는 극단적으로 클래스 이름만 선언을 하고 구현부에서는 pass를 사용하고는 아무것도 정의하지 않았습니다. 하지만 62라인에서 보는 것처럼 Hero클래스에 정의된 say_hello메서드를 호출해서 사용할 수 있습니다. Dark클래스가 Hero클래스의 모든 것을 그대로 상속받았기 때문입니다.
Knight클래스와 Wizard클래스 역시 Hero클래스를 상속받았지만 Dark클래스와는 조금 다릅니다.
먼저 Knight클래스를 보면 22라인에서 __init__메서드가 자체적으로 정의되어 있습니다. 이런 것을 메서드 오버라이딩(Overriding)이라고 합니다. 똑 같은 메서드 이름을 사용하지만 다르게 동작하도록 정의한 겁니다. 일관성을 지키기 위해 부모 클래스에서 상속받은 메서드 명은 그대로 사용하지만 다른 클래스이니 동작도 클래스 특성에 맞게 다르게 구현하고 싶을 때 사용합니다.
26라인과 35라인의 attack메서드 역시 17라인에서 정의한 attack메서드를 오버라이딩해서 재정의한 것입니다.
마지막으로 38라인으로 보면 healing이라는 메서드를 정의했습니다. 이 메서드는 Hero메서드에는 전혀 없던 메서드입니다. 맞습니다! 자식 클래스는 부모 클래스로부터 상속받은 메서드 뿐만 아니라 자신만의 메서드까지 정의해서 사용할 수 있는 것입니다.
이상의 코드를 실행해 보면 아래와 같은 결과를 확인할 수 있습니다.
클래스는 단번에 이해하기에는 그리 쉽지 않은 개념입니다. 하지만 수많은 유저들이 동시에 온라인으로 게임하는 MMORPG같은 게임을 구현하기 위해서는 클래스가 필수라는 점을 명심하고 계속 공부해 나가면 뛰어난 객체지향프로그래머가 되는 것도 어렵기만 한 일은 아닙니다.
4.4 파이썬 재사용할 수 있는 프로그램 만들기-클래스(Class)
5.6 파이썬 파일럿 프로젝트 - 심플 텍스트 분석기 제작
6.3 파이썬 개발도구 PyCharm Project 만들기
'Programming > Python for Beginners' 카테고리의 다른 글
4.5 파이썬 모듈 사용하기-pip사용 (0) | 2017.11.05 |
---|---|
4.5 파이썬 모듈 사용하기-모듈(Modules) (0) | 2017.11.05 |
4.4 파이썬 재사용할 수 있는 프로그램 만들기-함수(Function) (0) | 2017.11.05 |
4.4 파이썬 재사용할 수 있는 프로그램 만들기 (0) | 2017.11.05 |
4.3 파이썬 프로그램 만들어보기-try~except/finally문 (0) | 2017.11.05 |